﻿#region ConvertFrom-WMIDate

function ConvertFrom-WMIDate
{
    Param(
        [ValidatePattern("\d\d\d\d\d\d\d\d\d\d\d\d\d\d\.\d\d\d\d\d\d-\d\d\d")]
        [Parameter(Mandatory=$true)]
        [String]$Date
    )
    [System.Management.ManagementDateTimeConverter]::ToDateTime($Date)
}

#endregion ConvertFrom-WMIDate


#region ConvertTo-WMIDate

function ConvertTo-WMIDate
{
    Param(
        [Parameter(Mandatory=$true)]
        [System.DateTime]$Date
    )
    [System.Management.ManagementDateTimeConverter]::ToDmtfDateTime($Date)
}

#endregion ConvertTo-WMIDate


#region ConvertFrom-BinaryIP 

function ConvertFrom-BinaryIP
{
        
    #.Synopsis 
    # Convert from Binary to an IP address
    #.Example 
    # Convertfrom-BinaryIP -IP 11000000.10101000.00000001.00000001
    # AUTHOR:    Glenn Sizemore
    # Website:   http://get-admin.com
    Param (
        [string]
        $IP
    )
    process 
    {
    
        $out = @()
        foreach ($octet in $IP.split('.')) 
        {
            $strout = 0
            0..7|% {
                $bit = $octet.Substring(($_),1)
                if ($bit -eq 1) 
                { 
                    $strout = $strout + [math]::pow(2,(7-$_))
                } 
            }
            $out += $strout
        }
        return [string]::join('.',$out)
        
    }
}
    
#endregion 


#region ConvertFrom-MaskLength 

function ConvertFrom-MaskLength
{
        
    #.Synopsis 
    # Convert from masklength to a netmask
    #.Example 
    # ConvertFrom-MaskLength -Mask /24
    #.Example 
    # ConvertFrom-MaskLength -Mask 24
    # AUTHOR:    Glenn Sizemore
    # Website:   http://get-admin.com
    
    Param (
        [string]
        $mask
    )
    process {
    
        $out = @()
        if($mask -match "^/")
        {
            [int]$myMask = $mask -replace "/",""
        }
        else
        {
            [int]$myMask = $mask
        }
        [int]$wholeOctet = ($myMask - ($myMask % 8))/8
        if ($wholeOctet -gt 0) 
        {
            1..$($wholeOctet) |%{
                $out += "255"
            }
        }
        $subnet = ($myMask - ($wholeOctet * 8))
        if ($subnet -gt 0) 
        {
            $octet = 0
            0..($subnet - 1) | %{
                $octet = $octet + [math]::pow(2,(7-$_))
            }
            $out += $octet
        }
        for ($i=$out.count;$i -lt 4; $I++) 
        {
            $out += 0
        }
        return [string]::join('.',$out)
    
    }
}
    
#endregion 


#region ConvertTo-BinaryIP 

function ConvertTo-BinaryIP
{
        
    #.Synopsis
    # Convert an IP address to binary
    #.Example 
    # ConvertTo-BinaryIP -IP 192.168.1.1
    # AUTHOR:    Glenn Sizemore
    # Website:   http://get-admin.com
    Param (
        [string]$IP
    )
    begin {
    
        if($IP -match "(^/\d\d$|^\d\d$)")
        {
            $Address = ConvertFrom-MaskLength $IP
        }
        else
        {
            $Address = $IP
        }
        $out = @()
        foreach ($octet in $Address.split('.'))
        {
            $strout = $null
            0..7|% {
                if (($octet - [math]::pow(2,(7-$_)))-ge 0) 
                { 
                    $octet = $octet - [math]::pow(2,(7-$_))
                    [string]$strout = $strout + "1"
                }
                else 
                {
                    [string]$strout = $strout + "0"
                }   
            }
            $out += $strout
        }
        return [string]::join('.',$out)
        
    }
}
    
#endregion 


#region ConvertTo-MaskLength 

function ConvertTo-MaskLength
{
        
    #.Synopsis 
    # Convert from a netmask to the masklength
    #.Example 
    # ConvertTo-MaskLength -Mask 255.255.255.0
    # AUTHOR:    Glenn Sizemore
    # Website:   http://get-admin.com
    Param (
        [string]$mask
    )
    process {
    
        $out = 0
        foreach ($octet in $Mask.split('.')) 
        {
            $strout = 0
            0..7|% {
                if (($octet - [math]::pow(2,(7-$_)))-ge 0) 
                { 
                    $octet = $octet - [math]::pow(2,(7-$_))
                    $out++
                }
            }
        }
        return $out
        
    }
}
    
#endregion 


#region EditHosts.ps1 

function EditHosts 
{
    notepad $env:SystemRoot\system32\drivers\etc\hosts

}
    
#endregion 


#region Export-Credential 

function Export-Credential 
{
    <#
        .Synopsis 
            Exports the PSCredential securely to a file.
            
        .Description
            Exports the PSCredential securely to a file.
            
        .Parameter File
            File to export to.
        
        .Parameter Credential
            PSCredential to Export to file
            
        .Parameter RequirePassword
            [Switch] :: If passed a password is request to encrypt with.
        
        .Example
            Export-Credential -file c:\temp\mycred.pwf
            Description
            -----------
            Promps for creds and stores them to c:\temp\mycred.pwf
    
        .OUTPUTS
            FileInfo
            
        .INPUTS
            System.String
            
        .Link
            Import-Credential
            
        .Notes
            NAME:      Export-Credential
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [Parameter(Mandatory=$true)]
        [string]$File,
        
        [Parameter()]
        [System.Management.Automation.PSCredential]$Credential = (Get-Credential),
        
        [Parameter()]
        [Switch]$RequirePassword
    )
    
    function GetSecurePass ($SecurePassword) 
    {
        $Ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($SecurePassword)
        $password = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($Ptr)
        [System.Runtime.InteropServices.Marshal]::ZeroFreeCoTaskMemUnicode($Ptr)
        $password
    }
        
    $MyCredentialObject = New-Object PSCustomObject
    
    # Get Password to Encrypt the Creds with
    if($RequirePassword)
    {
        $spwd = Read-Host -prompt "Enter Password to Encrypt With" -asSecureString
        
        # Creating the Key for ConvertFrom-SecureString
        $ByteArrayforPassword = [System.Text.Encoding]::Unicode.GetBytes((GetSecurePass $spwd))
        if($ByteArrayforPassword.count -gt 24)
        {
            $key = @()
            [system.Array]::Copy($ByteArrayforPassword,$Key,24)
        }
        else
        {
            $key = $ByteArrayforPassword
            while($key.count -lt 24){$key += [byte]"11"}
        }
        
        $PasswordString = $credential.Password | ConvertFrom-SecureString -key $key
        Add-Member -InputObject $MyCredentialObject -MemberType NoteProperty -Name UserName -Value $credential.UserName
        Add-Member -InputObject $MyCredentialObject -MemberType NoteProperty -Name Password -Value $PasswordString
        $MyCredentialObject | Export-Clixml -Path $File 
        
        Get-Item $File
        
    }
    else
    {
        
        $PasswordString = ($credential.Password | ConvertFrom-SecureString)
        Add-Member -InputObject $MyCredentialObject -MemberType NoteProperty -Name UserName -Value $credential.UserName
        Add-Member -InputObject $MyCredentialObject -MemberType NoteProperty -Name Password -Value $PasswordString
        
        $MyCredentialObject | Export-Clixml -Path $File 
        
        Get-Item $File
        
    }
}
    
#endregion 


#region Get-CPUUsage 

function Get-CPUUsage
{
        
    <#
        .Synopsis 
            Gets the CPU usage for specified host.
            
        .Description
            Gets the CPU usage for specified host.
            
        .Parameter ComputerName
            Name of the Computer to get the CPU Usage from (Default is localhost.)
            
        .Example
            Get-CPUUsage
            Description
            -----------
            Gets CPU usage from local machine
    
        .Example
            Get-CPUUsage -ComputerName MyServer
            Description
            -----------
            Gets CPU usage from MyServer
            
        .Example
            $Servers | Get-CPUUsage
            Description
            -----------
            Gets CPU usage for each machine in the pipeline
            
        .OUTPUTS
            PSCustomObject
            
        .Notes
            NAME:      Get-CPUUsage
            AUTHOR:    YetiCentral\bshell
            Website:   www.bsonposh.com
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME
    )
    
    Process 
    {
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        if(Test-Host $ComputerName -TCPPort 135)
        {
            try
            {
                $CPUs = Get-WmiObject Win32_PerfFormattedData_PerfOS_Processor -comp $ComputerName -ea STOP -Filter "Name!='_Total'"
                
                foreach($CPU in $CPUs)
                {
                    $myobj = @{}
                    $myobj.ComputerName   = $ComputerName
                    $myobj.CPU            = $CPU.Name
                    $myobj.Idle           = $CPU.PercentIdleTime
                    $myobj.Interrupt      = $CPU.PercentInterruptTime
                    $myobj.Privileged     = $CPU.PercentPrivilegedTime
                    $myobj.Processor      = $CPU.PercentProcessorTime
                    $myobj.User           = $CPU.PercentUserTime
                
                    $obj = New-Object PSObject -Property $myobj
                    $obj.PSTypeNames.Clear()
                    $obj.PSTypeNames.Add('BSonPosh.CPUUsage')
                    $obj
                }
            }
            catch
            {
                Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
            }
        }
        else
        {
            Write-Host " Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
        }
    }
}
    
#endregion 


#region Get-DiskPartition 

function Get-DiskPartition
{
        
    <#
        .Synopsis 
            Gets the disk partition info for specified host
            
        .Description
            Gets the disk partition info for specified host
            
        .Parameter ComputerName
            Name of the Computer to get the disk partition info from (Default is localhost.)
            
        .Example
            Get-DiskPartition
            Description
            -----------
            Gets Disk Partitions from local machine
    
        .Example
            Get-DiskPartition -ComputerName MyServer
            Description
            -----------
            Gets Disk Partitions from MyServer
            
        .Example
            $Servers | Get-DiskPartition
            Description
            -----------
            Gets Disk Partitions for each machine in the pipeline
            
        .OUTPUTS
            PSObject
            
        .Notes
        NAME:      Get-DiskPartition 
        AUTHOR:    YetiCentral\bshell
        Website:   www.bsonposh.com
        #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME
    )
    
    Process 
    {
        Write-Verbose " [Get-DiskPartition] :: Process Start"
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        if(Test-Host $ComputerName -TCPPort 135)
        {
            try
            {
                Write-Verbose " [Get-DiskPartition] :: Getting Partition info use WMI"
                $Partitions = Get-WmiObject Win32_DiskPartition -ComputerName $ComputerName
                Write-Verbose " [Get-DiskPartition] :: Found $($Partitions.Count) partitions" 
                foreach($Partition in $Partitions)
                {
                    Write-Verbose " [Get-DiskPartition] :: Creating Hash Table"
                    $myobj = @{}
                    
                    Write-Verbose " [Get-DiskPartition] :: Adding BlockSize        - $($Partition.BlockSize)"
                    $myobj.BlockSize = $Partition.BlockSize
                    
                    Write-Verbose " [Get-DiskPartition] :: Adding BootPartition    - $($Partition.BootPartition)"
                    $myobj.BootPartition = $Partition.BootPartition
                    
                    Write-Verbose " [Get-DiskPartition] :: Adding ComputerName     - $ComputerName"
                    $myobj.ComputerName = $ComputerName
                    
                    Write-Verbose " [Get-DiskPartition] :: Adding Description      - $($Partition.name)"
                    $myobj.Description = $Partition.Name
                    
                    Write-Verbose " [Get-DiskPartition] :: Adding PrimaryPartition - $($Partition.PrimaryPartition)"
                    $myobj.PrimaryPartition = $Partition.PrimaryPartition
                    
                    Write-Verbose " [Get-DiskPartition] :: Adding Index            - $($Partition.Index)"
                    $myobj.Index = $Partition.Index
                    
                    Write-Verbose " [Get-DiskPartition] :: Adding SizeMB           - $($Partition.Size)"
                    $myobj.SizeMB = ($Partition.Size/1mb).ToString("n2",$Culture)
                    
                    Write-Verbose " [Get-DiskPartition] :: Adding Type             - $($Partition.Type)"
                    $myobj.Type = $Partition.Type
                    
                    Write-Verbose " [Get-DiskPartition] :: Setting IsAligned "
                    $myobj.IsAligned = $Partition.StartingOffset%64kb -eq 0
                    
                    Write-Verbose " [Get-DiskPartition] :: Creating Object"
                    $obj = New-Object PSObject -Property $myobj
                    $obj.PSTypeNames.Clear()
                    $obj.PSTypeNames.Add('BSonPosh.DiskPartition')
                    $obj
                }
            }
            catch
            {
                Write-Verbose " [Get-DiskPartition] :: [$ComputerName] Failed with Error: $($Error[0])" 
            }
        }
        Write-Verbose " [Get-DiskPartition] :: Process End"
    }
}
    
#endregion 


#region Get-DiskSpace 

function Get-DiskSpace 
{
        
    <#
        .Synopsis  
            Gets the disk space for specified host
            
        .Description
            Gets the disk space for specified host
            
        .Parameter ComputerName
            Name of the Computer to get the diskspace from (Default is localhost.)
            
        .Example
            Get-Diskspace
            # Gets diskspace from local machine
    
        .Example
            Get-Diskspace -ComputerName MyServer
            Description
            -----------
            Gets diskspace from MyServer
            
        .Example
            $Servers | Get-Diskspace
            Description
            -----------
            Gets diskspace for each machine in the pipeline
            
        .OUTPUTS
            PSCustomObject
            
        .Notes
            NAME:      Get-DiskSpace 
            AUTHOR:    YetiCentral\bshell
            Website:   www.bsonposh.com
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME
    )
    
    Begin 
    {
        Write-Verbose " [Get-DiskSpace] :: Start Begin"
        $Culture = New-Object System.Globalization.CultureInfo("en-US") 
        Write-Verbose " [Get-DiskSpace] :: End Begin"
    }
    
    Process 
    {
        Write-Verbose " [Get-DiskSpace] :: Start Process"
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
            
        }
        Write-Verbose " [Get-DiskSpace] :: `$ComputerName - $ComputerName"
        Write-Verbose " [Get-DiskSpace] :: Testing Connectivity"
        if(Test-Host $ComputerName -TCPPort 135)
        {
            Write-Verbose " [Get-DiskSpace] :: Connectivity Passed"
            try
            {
                Write-Verbose " [Get-DiskSpace] :: Getting Operating System Version using - Get-WmiObject Win32_OperatingSystem -ComputerName $ComputerName -Property Version"
                $OSVersionInfo = Get-WmiObject Win32_OperatingSystem -ComputerName $ComputerName -Property Version -ea STOP
                Write-Verbose " [Get-DiskSpace] :: Getting Operating System returned $($OSVersionInfo.Version)"
                if($OSVersionInfo.Version -gt 5.2)
                {
                    Write-Verbose " [Get-DiskSpace] :: Version high enough to use Win32_Volume"
                    Write-Verbose " [Get-DiskSpace] :: Calling Get-WmiObject -class Win32_Volume -ComputerName $ComputerName -Property `"Name`",`"FreeSpace`",`"Capacity`" -filter `"DriveType=3`""
                    $DiskInfos = Get-WmiObject -class Win32_Volume                          `
                                            -ComputerName $ComputerName                  `
                                            -Property "Name","FreeSpace","Capacity"      `
                                            -filter "DriveType=3" -ea STOP
                    Write-Verbose " [Get-DiskSpace] :: Win32_Volume returned $($DiskInfos.count) disks"
                    foreach($DiskInfo in $DiskInfos)
                    {
                        $myobj = @{}
                        $myobj.ComputerName = $ComputerName
                        $myobj.OSVersion    = $OSVersionInfo.Version
                        $Myobj.Drive        = $DiskInfo.Name
                        $Myobj.CapacityGB   = [float]($DiskInfo.Capacity/1GB).ToString("n2",$Culture)
                        $Myobj.FreeSpaceGB  = [float]($DiskInfo.FreeSpace/1GB).ToString("n2",$Culture)
                        $Myobj.PercentFree  = "{0:P2}" -f ($DiskInfo.FreeSpace / $DiskInfo.Capacity)
                        $obj = New-Object PSObject -Property $myobj
                        $obj.PSTypeNames.Clear()
                        $obj.PSTypeNames.Add('BSonPosh.DiskSpace')
                        $obj
                    }
                }
                else
                {
                    Write-Verbose " [Get-DiskSpace] :: Version not high enough to use Win32_Volume using Win32_LogicalDisk"
                    $DiskInfos = Get-WmiObject -class Win32_LogicalDisk                       `
                                            -ComputerName $ComputerName                       `
                                            -Property SystemName, DeviceID, FreeSpace, Size   `
                                            -filter "DriveType=3" -ea STOP
                    foreach($DiskInfo in $DiskInfos)
                    {
                        $myobj = @{}
                        $myobj.ComputerName = $ComputerName
                        $myobj.OSVersion    = $OSVersionInfo.Version
                        $Myobj.Drive       = "{0}\" -f $DiskInfo.DeviceID
                        $Myobj.CapacityGB   = [float]($DiskInfo.Capacity/1GB).ToString("n2",$Culture)
                        $Myobj.FreeSpaceGB  = [float]($DiskInfo.FreeSpace/1GB).ToString("n2",$Culture)
                        $Myobj.PercentFree  = "{0:P2}" -f ($DiskInfo.FreeSpace / $DiskInfo.Capacity)
                        $obj = New-Object PSObject -Property $myobj
                        $obj.PSTypeNames.Clear()
                        $obj.PSTypeNames.Add('BSonPosh.DiskSpace')
                        $obj
                    }
                }
            }
            catch
            {
                Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
            }
        }
        else
        {
            Write-Host " Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
        }
        Write-Verbose " [Get-DiskSpace] :: End Process"
    
    }
}
    
#endregion 


#region Get-Processor

function Get-Processor
{
        
    <#
        .Synopsis 
            Gets the Computer Processor info for specified host.
            
        .Description
            Gets the Computer Processor info for specified host.
            
        .Parameter ComputerName
            Name of the Computer to get the Computer Processor info from (Default is localhost.)
            
        .Example
            Get-Processor
            Description
            -----------
            Gets Computer Processor info from local machine
    
        .Example
            Get-Processor -ComputerName MyServer
            Description
            -----------
            Gets Computer Processor info from MyServer
            
        .Example
            $Servers | Get-Processor
            Description
            -----------
            Gets Computer Processor info for each machine in the pipeline
            
        .OUTPUTS
            PSCustomObject
            
        .INPUTS
            System.String
            
        .Link
            N/A
            
        .Notes
            NAME:      Get-Processor
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME
    )
    
    Process 
    {
    
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        if(Test-Host -ComputerName $ComputerName -TCPPort 135)
        {
            try
            {
                $CPUS = Get-WmiObject Win32_Processor -ComputerName $ComputerName -ea STOP
                foreach($CPU in $CPUs)
                {
                    $myobj = @{
                        ComputerName = $ComputerName
                        Name         = $CPU.Name
                        Manufacturer = $CPU.Manufacturer
                        Speed        = $CPU.MaxClockSpeed
                        Cores        = $CPU.NumberOfCores
                        L2Cache      = $CPU.L2CacheSize
                        Stepping     = $CPU.Stepping
                    }
                    $obj = New-Object PSObject -Property $myobj
                    $obj.PSTypeNames.Clear()
                    $obj.PSTypeNames.Add('BSonPosh.Computer.Processor')
                    $obj
                }
            }
            catch
            {
                Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
            }
        }
        else
        {
            Write-Host " Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
        }
    
    }
}
    
#endregion # Get-Processor


#region Get-FileMD5 

function Get-FileMD5
{
        
    <#
        .Synopsis 
            Gets the MD5 hash of the file(s).
            
        .Description
            Gets the MD5 hash of the file(s) using the ComputeHash() method of System.Security.Cryptography.MD5CryptoServiceProvider.
            
        .Parameter Path
            Path to the file to caculate hash for.
            
        .Example
            Get-FileMD5 c:\temp\myfile.ps1
            Description
            -----------
            Gets the MD5 hash for the file c:\temp\myfile.ps1
    
        .Example
            dir c:\temp\myscripts | Get-FileMD5 
            Description
            -----------
            Gets the MD5 hash for all the files in c:\temp\myscripts
            
        .OUTPUTS
            PSCustomObject
            
        .INPUTS
            System.String
        
        .Notes
            NAME:      Get-FileMD5
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [CmdletBinding()]
    Param(
    
        [alias("FullName")]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true,Mandatory=$true)]
        [string]$Path
        
    )
    Process 
    {
        Write-Verbose " [Get-FileMD5] :: Start Process"
        $Parent = Split-Path $Path -Parent
        $File = Split-Path $Path -Leaf
        
        if($Parent -and ($Parent -ne "."))
        {
            Write-Verbose " [Get-FileMD5] :: Parent Folder = $Parent"
            $FilePath = $path
        }
        else
        {
            Write-Verbose " [Get-FileMD5] :: No Parent found. Using current Path"
            $FilePath = "$pwd\$File"            
        }
        
        Write-Verbose " [Get-FileMD5] :: Using $FilePath"
    
        try
        {
            Write-Verbose " [Get-FileMD5] :: Getting Handle to file"
            $mode = [System.IO.FileMode]("open")
            $item = Get-Item $FilePath
            
            if($item -is [System.IO.FileInfo])
            {
                $md5 = New-Object System.Security.Cryptography.MD5CryptoServiceProvider
                Write-Verbose " [Get-FileMD5] :: Opening File Stream"
                $fs = $item.Open($mode)
                
                Write-Verbose " [Get-FileMD5] :: Getting MD5"
                $MD5Hash = ($md5.ComputeHash($fs) | %{$_.ToString("x").ToUpper()}) -join ""
                
                Write-Verbose " [Get-FileMD5] :: Closing file"
                $fs.Close()
                
                Write-Verbose " [Get-FileMD5] :: Returning MD5 object"
                $myobjProperties = @{}
                $myobjProperties.Path = $Path
                $myobjProperties.MD5 = $MD5Hash
    
                $obj = New-Object PSObject -Property $myobjProperties
                $obj.PSTypeNames.Clear()
                $obj.PSTypeNames.Add('BSonPosh.MD5Hash')
                $obj
            }
        }
        catch
        {
            $myobjProperties.Hash = "Unable to open file $FilePath"
            Write-Host "Unable to open file $FilePath. Error: $($Error[0])."
            Continue
        }
        
        Write-Verbose " [Get-FileMD5] :: End Process"
    
    }
}
    
#endregion 


#region Get-IP 

function Get-IP
{
        
    <#
        .Synopsis 
            Get the IP of the specified host.
            
        .Description
            Get the IP of the specified host.
            
        .Parameter ComputerName
            Name of the Computer to get IP (Default localhost.)
                
        .Example
            Get-IP
            Description
            -----------
            Get IP information the localhost
            
            
        .OUTPUTS
            PSCustomObject
            
        .INPUTS
            System.String
        
        .Notes
            NAME:      Get-IP
            AUTHOR:    YetiCentral\bshell
            Website:   www.bsonposh.com
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME
    )
    Process
    {
        $NICs = Get-WmiObject Win32_NetworkAdapterConfiguration -Filter "IPEnabled='$True'" -ComputerName $ComputerName
        foreach($Nic in $NICs)
        {
            $myobj = @{
                ComputerName  = $ComputerName
                Name          = $Nic.Description
                MacAddress    = $Nic.MACAddress
                IP4           = $Nic.IPAddress | where{$_ -match "\d+\.\d+\.\d+\.\d+"}
                IP6           = $Nic.IPAddress | where{$_ -match "\:\:"}
                IP4Subnet     = $Nic.IPSubnet  | where{$_ -match "\d+\.\d+\.\d+\.\d+"}
                DefaultGWY    = $Nic.DefaultIPGateway | Select -First 1
                DNSServer     = $Nic.DNSServerSearchOrder
                WINSPrimary   = $Nic.WINSPrimaryServer
                WINSSecondary = $Nic.WINSSecondaryServer
            }
            $obj = New-Object PSObject -Property $myobj
            $obj.PSTypeNames.Clear()
            $obj.PSTypeNames.Add('BSonPosh.IPInfo')
            $obj
        }
    }
}
    
#endregion 


#region Get-IPRange 

function Get-IPRange
{
        
    <#
        .Synopsis 
            Given an IP and Subnet Mask it return all  IP in the same IP network.
            
        .Description
            Given an IP and Subnet Mask it return all  IP in the same IP network.
                        
        .Parameter IP 
            IP of a host on the Network.
            
        .Parameter Network 
            Network Address.
        
        .Example
            Get-IPRange -IP 192.168.1.0 -Mask 255.255.255.0
            Description
            -----------
            Returns all host on 192.168.1.0 network using mask 255.255.255.0
            
        .Example
            Get-IPRange -IP 192.168.1.0 -Mask /24
            Description
            -----------
            Returns all host on 192.168.1.0 network using CIDR notation
            
        .OUTPUTS
            System.String
            
        .INPUTS
            System.String
            
        .Link
            Ping-Subnet
            Invoke-Pingmonitor
            Get-NetworkAddress
            ConvertTo-BinaryIP 
            ConvertFrom-BinaryIP 
            ConvertTo-MaskLength 
            ConvertFrom-MaskLength 
            
        .Notes    
            NAME:      Get-IPRange
            AUTHOR:    Glenn Sizemore
            Website:   http://get-admin.com
            Version:   1
            #Requires -Version 2.0
    #>
        
    [Cmdletbinding()]
    Param (
        [Parameter()]
        [string]$IP,
        
        [Alias("mask")]
        [Parameter()]
        [string]$netmask
    )
    Process 
    {
    
        Write-Verbose  " [Get-IPRange] :: Process start"
        
        if ($netMask -match "(^\d\d$)|(^/\d\d$)") 
        {
            Write-Verbose  " [Get-IPRange] :: Converting $netmask to $($netmask.replace('/',''))"
            $masklength = $netmask.replace('/','')
            $Subnet = ConvertFrom-MaskLength $masklength
            Write-Verbose  " [Get-IPRange] :: Subnet :: $Subnet"
        } 
        else 
        {
            Write-Verbose " [Get-IPRange] :: Using $netmask"
            $Subnet = $netmask
            $masklength = ConvertTo-MaskLength -Mask $netmask
            Write-Verbose " [Get-IPRange] :: Subnet :: $Subnet"
        }
        
        Write-Verbose " [Get-IPRange] :: Getting Network Address - Get-NetworkAddress -IP $IP -Mask $Subnet "
        $network = Get-NetworkAddress -IP $IP -Mask $Subnet 
        Write-Verbose " [Get-IPRange] :: returned $Network"
        
        [int]$FirstOctet,[int]$SecondOctet,[int]$ThirdOctet,[int]$FourthOctet = $network.split('.')
        
        Write-Verbose " [Get-IPRange] :: Getting Total number of IPs"
        $TotalIPs = ([math]::pow(2,(32-$masklength)) -2)
        Write-Verbose " [Get-IPRange] :: Result = $TotalIPs"
        
        Write-Verbose " [Get-IPRange] :: Getting IPs"
        
        $blocks = ($TotalIPs - ($TotalIPs % 256))/256
        if ($Blocks -gt 0) 
        {
            1..$blocks | %{
                0..255 |%{
                    if ($FourthOctet -eq 255) 
                    {
                        if ($ThirdOctet -eq 255) 
                        {
                            if ($SecondOctet -eq 255) 
                            {
                                $FirstOctet++
                                $secondOctet = 0
                            } 
                            else 
                            {
                                $SecondOctet++
                                $ThirdOctet = 0
                            }
                        } 
                        else 
                        {
                            $FourthOctet = 0
                            $ThirdOctet++
                        }  
                    } 
                    else 
                    {
                        $FourthOctet++
                    }
                    Write-Output ("{0}.{1}.{2}.{3}" -f `
                    $FirstOctet,$SecondOctet,$ThirdOctet,$FourthOctet)
                }
            }
        }
        
        $sBlock = $TotalIPs - ($blocks * 256)
        
        if ($sBlock -gt 0) 
        {
            1..$SBlock | %{
                if ($FourthOctet -eq 255)
                {
                    if ($ThirdOctet -eq 255) 
                    {
                        if ($SecondOctet -eq 255) 
                        {
                            $FirstOctet++
                            $secondOctet = 0
                        } 
                        else 
                        {
                            $SecondOctet++
                            $ThirdOctet = 0
                        }
                    } 
                    else 
                    {
                        $FourthOctet = 0
                        $ThirdOctet++
                    }  
                } 
                else 
                {
                    $FourthOctet++
                }
                Write-Output ("{0}.{1}.{2}.{3}" -f `
                $FirstOctet,$SecondOctet,$ThirdOctet,$FourthOctet)
            }
        }
        
        Write-Verbose  " [Get-IPRange] :: Process End"
    
    }
}
    
#endregion 


#region Get-InstalledSoftware

function Get-InstalledSoftware
{

    <#
        .Synopsis
            Gets the installed software using Uninstall regkey for specified host.

        .Description
            Gets the installed software using Uninstall regkey for specified host.

        .Parameter ComputerName
            Name of the Computer to get the installed software from (Default is localhost.)

        .Example
            Get-InstalledSoftware
            Description
            -----------
            Gets installed software from local machine

        .Example
            Get-InstalledSoftware -ComputerName MyServer
            Description
            -----------
            Gets installed software from MyServer

        .Example
            $Servers | Get-InstalledSoftware
            Description
            -----------
            Gets installed software for each machine in the pipeline

        .OUTPUTS
            PSCustomObject

        .Notes
            NAME:      Get-InstalledSoftware
            AUTHOR:    YetiCentral\bshell
            Website:   www.bsonposh.com
            #Requires -Version 2.0
    #>

    [Cmdletbinding()]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME
    )
    begin 
    {

            Write-Verbose " [Get-InstalledPrograms] :: Start Begin"
            $Culture = New-Object System.Globalization.CultureInfo("en-US")
            Write-Verbose " [Get-InstalledPrograms] :: End Begin"

    }
    process 
    {

        Write-Verbose " [Get-InstalledPrograms] :: Start Process"
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'

        }
        Write-Verbose " [Get-InstalledPrograms] :: `$ComputerName - $ComputerName"
        Write-Verbose " [Get-InstalledPrograms] :: Testing Connectivity"
        if(Test-Host $ComputerName -TCPPort 135)
        {
            try
            {
                $RegKey = Get-RegistryKey -Path "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" -ComputerName $ComputerName
                foreach($key in $RegKey.GetSubKeyNames())   
                {   
                    $SubKey = $RegKey.OpenSubKey($key)
                    if($SubKey.GetValue("DisplayName"))
                    {
                        $myobj = @{
                            Name    = $SubKey.GetValue("DisplayName")   
                            Version = $SubKey.GetValue("DisplayVersion")   
                            Vendor  = $SubKey.GetValue("Publisher")
                        }
                        $obj = New-Object PSObject -Property $myobj
                        $obj.PSTypeNames.Clear()
                        $obj.PSTypeNames.Add('BSonPosh.SoftwareInfo')
                        $obj
                    }
                }   
            }
            catch
            {
                Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
            }
        }
        else
        {
            Write-Host " Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
        }
        Write-Verbose " [Get-InstalledPrograms] :: End Process"

    }
}

#endregion 


#region Get-LocalGroupMember 

function Get-LocalGroupMember
{
        
    <#
        .Synopsis
            Get the local group membership.
            
        .Description
            Get the local group membership.
            
        .Parameter ComputerName
            Name of the Computer to get group members (Default localhost.)
            
        .Parameter Group
            Name of the group to get members from (Default Administrators.)
            
        .Example
            Get-LocalGroupMember
            Description
            -----------
            Get Administrators group Members for the localhost
            
        .Example
            Get-LocalGroupMember -Computer MyPC -group User
            Description
            -----------
            Get Members of Users Group from MyPC
            
        .Example
            $Servers | Get-LocalGroupMember -group "Remote Desktop Users"
            Description
            -----------
            Get Members of Users Group from "Remote Desktop Users" on all $Servers
            
        .OUTPUTS
            PSCustomObject
            
        .INPUTS
            System.String
            
        .Link
            N/A
        
        .Notes
            NAME:      Get-LocalGroupMember
            AUTHOR:    YetiCentral\bshell
            Website:   www.bsonposh.com
            LASTEDIT:  10/13/2009 18:25:15
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME,
        
        [Parameter()]
        [string]$Group= "Administrators"
    )
    Begin 
    {
    
        Write-Verbose " [Get-LocalGroupMember] :: Start Begin"
        function GetGroupMembers($Server,$Group)
        {
            Write-Verbose " [Get-LocalGroupMember] :: GetGroupMembers :: `$Server = $Server"
            Write-Verbose " [Get-LocalGroupMember] :: GetGroupMembers :: `$Group = $Group"
            
            $GroupObject = Get-WMIObject win32_group -filter "LocalAccount='$true' AND Name='$Group'" -computername $Server -ea STOP
            
            $Query = "SELECT * FROM Win32_GroupUser WHERE GroupComponent = `"Win32_Group.Domain='$Server',Name='$Group'`""
            Write-Verbose " [Get-LocalGroupMember] :: GetGroupMembers :: `$Query = $Query"
            $GroupUsers = get-wmiobject -Query $Query -computername $Server  -ea STOP
            
            Write-Verbose " [Get-LocalGroupMember] :: GetGroupMembers :: Processing Group Members "
            
            if($GroupUsers)
            {
                foreach($User in $GroupUsers)
                {
                    Write-Verbose " [Get-LocalGroupMember] :: GetGroupMembers :: `$User.PartComponent = $($User.PartComponent)"
                    
                    $RegEx = '\\\\{0}\\root\\cimv2\:Win32_.*\="(?<Domain>.*)",Name="(?<User>.*)"' -f $Server
                    Write-Verbose " [Get-LocalGroupMember] :: GetGroupMembers :: RegEx = $RegEx "
                    $User.PartComponent -match $Regex | out-null
                    
                    Write-Verbose " [Get-LocalGroupMember] :: GetGroupMembers :: Creating Custom Object "
                    $myobj = @{}
                    Write-Verbose " [Get-LocalGroupMember] :: GetGroupMembers :: `$myobj.ComputerName = $Server"
                    $myobj.ComputerName = $Server
                    Write-Verbose " [Get-LocalGroupMember] :: GetGroupMembers :: `$myobj.UserName = $($matches.User)"
                    $myobj.UserName = $matches.User
                    Write-Verbose " [Get-LocalGroupMember] :: GetGroupMembers :: `$myobj.Domain = $($matches.Domain)"
                    $myobj.Domain = $matches.Domain
                    Write-Verbose " [Get-LocalGroupMember] :: GetGroupMembers :: `$myobj.Group = $Group"
                    $myobj.Group = $Group
                    $obj = New-Object PSObject -Property $myobj
                    $obj.PSTypeNames.Clear()
                    $obj.PSTypeNames.Add('BSonPosh.LocalGroup')
                    $obj
                }
            }
        }
        
        Write-Verbose " [Get-LocalGroupMember] :: End Begin"
    
    }
    Process 
    {
    
        Write-Verbose " [Get-LocalGroupMember] :: Start Process"
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        if(Test-Host $ComputerName -TCPPort 135)
        {
            Write-Verbose " [Get-LocalGroupMember] :: Processing Computer: $ComputerName"
            try
            {
                GetGroupMembers $ComputerName $Group
            }
            catch
            {
                Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
            }
        }
        else
        {
            Write-Host " Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
        }
        Write-Verbose " [Get-LocalGroupMember] :: End Process"
    
    }
}
    
#endregion 


#region New-LocalGroupMember

function New-LocalGroupMember
{
    <#
        .Synopsis
            Adds a user or group to the local group specified.
            
        .Description
            Adds a user or group to the local group specified.
            
        .Parameter ComputerName
            Name of the Computer to add group member on (Default localhost.)
            
        .Parameter Group
            Name of the group to add members to (Default Administrators.)
            
        .Example
            New-LocalGroupMember -Member MyUser
            Description
            -----------
            Adds "MyUser" to local Administrators group on localhost
            
        .Example
            New-LocalGroupMember -Computer MyPC -Member "Domain\Domain Users" -group "Remote Desktop Users"
            Description
            -----------
            Adds "Domain\Domain Users" to the "Remote Desktop Users" Group on MyPC
            
        .Example
            $Servers | New-LocalGroupMember -group "Remote Desktop Users" -member MyUser
            Description
            -----------
            Add "MyUser" to the "Remote Desktop Users" group on all $Servers
            
        .OUTPUTS
            PSCustomObject
            
        .INPUTS
            System.String
            
        .Link
            N/A
        
        .Notes
            NAME:      New-LocalGroupMember
            AUTHOR:    YetiCentral\bshell
            Website:   www.bsonposh.com
            LASTEDIT:  10/07/2010
            #Requires -Version 2.0
    #>
    [CmdletBinding(SupportsShouldProcess=$True)]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME,
        
        [Parameter(Mandatory=$true)]
        [string]$Member,
        
        [Parameter()]
        [string]$Group = "Administrators"
    )
    Begin
    {
        $Member = $Member -replace "\\","/"
    }
    Process 
    {
    
        Write-Verbose " [New-LocalGroupMember] :: Start Process"
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        if(Test-Host $ComputerName -TCPPort 135)
        {
            Write-Verbose " [Get-LocalGroupMember] :: Processing Computer: $ComputerName"
            try
            {
                $computer = [ADSI]("WinNT://$ComputerName,computer")

                Write-Verbose " [New-LocalGroupMember] :: Searching Computer for Group"
                $GroupObj = $Computer.Children.Find($Group,"Group")

                Write-Verbose " [New-LocalGroupMember] :: Group [$($GroupObj.Name)] found!"
                Write-Verbose " [New-LocalGroupMember] :: Adding $Member to $Group"

                try 
                {
                    if($PSCmdlet.ShouldProcess($GroupObj.Name,"Adding [$Member] to Group on $ComputerName"))
                    {
                        $GroupObj.Add("WinNT://$Member")
                    }
                } 
                catch 
                {
                    Write-Verbose " [New-LocalGroupMember] :: Exception occurred while adding $Member to $Group."
                    return
                }
            }
            catch
            {
                Write-Host " [New-LocalGroupMember] ::  Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
            }
        }
        else
        {
            Write-Host "  [New-LocalGroupMember] :: Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
        }
        Write-Verbose " [New-LocalGroupMember] :: End Process"
    
    }
}

#endregion


#region Remove-LocalGroupMember

function Remove-LocalGroupMember
{

    <#
        .Synopsis
            Removes a user or group to the local group specified.
            
        .Description
            Removes a user or group to the local group specified.
            
        .Parameter ComputerName
            Name of the Computer to Removes the group member on (Default localhost.)
            
        .Parameter Group
            Name of the group to Removes members to (Default Administrators.)
            
        .Example
            Remove-LocalGroupMember -Member MyUser
            Description
            -----------
            Removes "MyUser" from local Administrators group on localhost
            
        .Example
            Remove-LocalGroupMember -Computer MyPC -Member "Domain\Domain Users" -group "Remote Desktop Users"
            Description
            -----------
            Removes "Domain\Domain Users" from the "Remote Desktop Users" Group on MyPC
            
        .Example
            $Servers | Remove-LocalGroupMember -group "Remote Desktop Users" -member MyUser
            Description
            -----------
            Removes "MyUser" from the "Remote Desktop Users" group on all $Servers
            
        .OUTPUTS
            PSCustomObject
            
        .INPUTS
            System.String
            
        .Link
            N/A
        
        .Notes
            NAME:      Remove-LocalGroupMember
            AUTHOR:    YetiCentral\bshell
            Website:   www.bsonposh.com
            LASTEDIT:  10/07/2010
            #Requires -Version 2.0
    #>
    
    [CmdletBinding(SupportsShouldProcess=$True)]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME,
        
        [Parameter(Mandatory=$true)]
        [string]$Member,
        
        [Parameter()]
        [string]$Group = "Administrators"
    )
    Begin
    {
        $Member = $Member -replace "\\","/"
    }
    Process 
    {
    
        Write-Verbose " [Remove-LocalGroupMember] :: Start Process"
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        if(Test-Host $ComputerName -TCPPort 135)
        {
            Write-Verbose " [Remove-LocalGroupMember] :: Processing Computer: $ComputerName"
            try
            {
                $computer = [ADSI]("WinNT://$ComputerName,computer")

                Write-Verbose " [Remove-LocalGroupMember] :: Searching Computer for Group"
                $GroupObj = $Computer.Children.Find($Group,"Group")

                Write-Verbose " [Remove-LocalGroupMember] :: Group [$($GroupObj.Name)] found!"
                Write-Verbose " [Remove-LocalGroupMember] :: Removing $Member to $Group"

                try 
                {
                    if($PSCmdlet.ShouldProcess($GroupObj.Name,"Removing [$Member] to Group on $ComputerName"))
                    {
                        $GroupObj.Remove("WinNT://$Member")
                    }
                } 
                catch 
                {
                    Write-Verbose " [Remove-LocalGroupMember] :: Exception occurred while Removing $Member to $Group."
                    return
                }
            }
            catch
            {
                Write-Host " [Remove-LocalGroupMember] ::  Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
            }
        }
        else
        {
            Write-Host "  [Remove-LocalGroupMember] :: Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
        }
        Write-Verbose " [Remove-LocalGroupMember] :: End Process"
    
    }
}

#endregion


#region Get-MemoryConfiguration 

function Get-MemoryConfiguration
{
        
    <#
        .Synopsis 
            Gets the Memory Config for specified host.
            
        .Description
            Gets the Memory Config for specified host.
            
        .Parameter ComputerName
            Name of the Computer to get the Memory Config from (Default is localhost.)
            
        .Example
            Get-MemoryConfiguration
            Description
            -----------
            Gets Memory Config from local machine
    
        .Example
            Get-MemoryConfiguration -ComputerName MyServer
            Description
            -----------
            Gets Memory Config from MyServer
            
        .Example
            $Servers | Get-MemoryConfiguration
            Description
            -----------
            Gets Memory Config for each machine in the pipeline
            
        .OUTPUTS
            PSCustomObject
            
        .Notes
            NAME:      Get-MemoryConfiguration 
            AUTHOR:    YetiCentral\bshell
            Website:   www.bsonposh.com
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME
    )
    
    Process 
    {
    
        Write-Verbose " [Get-MemoryConfiguration] :: Begin Process"
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        if(Test-Host $ComputerName -TCPPort 135)
        {
            Write-Verbose " [Get-MemoryConfiguration] :: Processing $ComputerName"
            try
            {
                $MemorySlots = Get-WmiObject Win32_PhysicalMemory -ComputerName $ComputerName -ea STOP
                foreach($Dimm in $MemorySlots)
                {
                    $myobj = @{}
                    $myobj.ComputerName = $ComputerName
                    $myobj.Description  = $Dimm.Tag
                    $myobj.Slot         = $Dimm.DeviceLocator
                    $myobj.Speed        = $Dimm.Speed
                    $myobj.SizeGB       = $Dimm.Capacity/1gb
                    
                    $obj = New-Object PSObject -Property $myobj
                    $obj.PSTypeNames.Clear()
                    $obj.PSTypeNames.Add('BSonPosh.MemoryConfiguration')
                    $obj
                }
            }
            catch
            {
                Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
            }    
        }
        else
        {
            Write-Host " Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
        }
        Write-Verbose " [Get-MemoryConfiguration] :: End Process"
    
    }
}
    
#endregion 


#region Get-NetStat 
            #Need to Implement
            #[Parameter()]
            #[int]$ID,
            #[Parameter()]
            #[int]$RemotePort,
            #[Parameter()]
            #[string]$RemoteAddress,
function Get-NetStat
{

    <#
        .Synopsis 
            Get the Network stats of the local host.
            
        .Description
            Get the Network stats of the local host.
            
        .Parameter ProcessName
            Name of the Process to get Network stats for.
        
        .Parameter State
            State to return: Valid Values are: "LISTENING", "ESTABLISHED", "CLOSE_WAIT", or "TIME_WAIT"

        .Parameter Interval
            Number of times you want to run netstat. Cannot be used with Loop.
            
        .Parameter Sleep
            Time between calls to netstat. Used with Interval or Loop.
            
        .Parameter Loop
            Loops netstat calls until you press ctrl-c. Cannot be used with Internval.
            
        .Example
            Get-NetStat
            Description
            -----------
            Returns all Network stat information on the localhost
        
        .Example
            Get-NetStat -ProcessName chrome
            Description
            -----------
            Returns all Network stat information on the localhost for process chrome.
            
        .Example
            Get-NetStat -State ESTABLISHED
            Description
            -----------
            Returns all the established connections on the localhost
            
        .Example
            Get-NetStat -State ESTABLISHED -Loop
            Description
            -----------
            Loops established connections.
            
        .OUTPUTS
            PSCustomObject
            
        .INPUTS
            System.String
        
        .Notes
            NAME:      Get-NetStat
            AUTHOR:    YetiCentral\bshell
            Website:   www.bsonposh.com
            #Requires -Version 2.0

    #>
    
    [Cmdletbinding(DefaultParameterSetName="All")]
    Param(
        [Parameter()]
        [string]$ProcessName,

        [Parameter()]
        [ValidateSet("LISTENING", "ESTABLISHED", "CLOSE_WAIT","TIME_WAIT")]
        [string]$State,
        
        [Parameter(ParameterSetName="Interval")]
        [int]$Interval,
        
        [Parameter()]
        [int]$Sleep = 1,
        
        [Parameter(ParameterSetName="Loop")]
        [switch]$Loop
    )

    function Parse-Netstat ($NetStat)
    {
        Write-Verbose " [Parse-Netstat] :: Parsing Netstat results"
        switch -regex ($NetStat)
        {
            $RegEx  
            {
                Write-Verbose " [Parse-Netstat] :: creating Custom object"
                $myobj = @{
                    Protocol      = $matches.Protocol
                    LocalAddress  = $matches.LocalAddress.split(":")[0]
                    LocalPort     = $matches.LocalAddress.split(":")[1]
                    RemoteAddress = $matches.RemoteAddress.split(":")[0]
                    RemotePort    = $matches.RemoteAddress.split(":")[1]
                    State         = $matches.State
                    ProcessID     = $matches.PID
                    ProcessName   = Get-Process -id $matches.PID -ea 0 | %{$_.name}
                }
                
                $obj = New-Object PSCustomObject -Property $myobj
                $obj.PSTypeNames.Clear()
                $obj.PSTypeNames.Add('BSonPosh.NetStatInfo')
                Write-Verbose " [Parse-Netstat] :: Created object for [$($obj.LocalAddress):$($obj.LocalPort)]"
                
                if($ProcessName)
                {
                    $obj | where{$_.ProcessName -eq $ProcessName}
                }
                elseif($State)
                {
                    $obj | where{$_.State -eq $State}
                }
                else
                {
                    $obj
                }
                
            }
        }
    }
    
    [RegEX]$RegEx = '\s+(?<Protocol>\S+)\s+(?<LocalAddress>\S+)\s+(?<RemoteAddress>\S+)\s+(?<State>\S+)\s+(?<PID>\S+)'
    $Connections = @{}
    
    switch -exact ($pscmdlet.ParameterSetName)
    {    
        "All"           {
                            Write-Verbose " [Get-NetStat] :: ParameterSet - ALL"
                            $NetStatResults = netstat -ano | ?{$_ -match "(TCP|UDP)\s+\d"}
                            Parse-Netstat $NetStatResults
                        }
        "Interval"      {
                            Write-Verbose " [Get-NetStat] :: ParameterSet - Interval"
                            for($i = 1 ; $i -le $Interval ; $i++)
                            {
                                Start-Sleep $Sleep
                                $NetStatResults = netstat -ano | ?{$_ -match "(TCP|UDP)\s+\d"}
                                Parse-Netstat $NetStatResults | Out-String
                            }
                        }
        "Loop"          {
                            Write-Verbose " [Get-NetStat] :: ParameterSet - Loop"
                            Write-Host
                            Write-Host "Protocol LocalAddress  LocalPort RemoteAddress  RemotePort State       ProcessName   PID"
                            Write-Host "-------- ------------  --------- -------------  ---------- -----       -----------   ---" -ForegroundColor White
                            $oldPos = $Host.UI.RawUI.CursorPosition
                            [console]::TreatControlCAsInput = $true
                            while($true)
                            {
                                Write-Verbose " [Get-NetStat] :: Getting Netstat data"
                                $NetStatResults = netstat -ano | ?{$_ -match "(TCP|UDP)\s+\d"}
                                Write-Verbose " [Get-NetStat] :: Getting Netstat data from Netstat"
                                $Results = Parse-Netstat $NetStatResults 
                                Write-Verbose " [Get-NetStat] :: Parse-NetStat returned $($results.count) results"
                                foreach($Result in $Results)
                                {
                                    $Key = $Result.LocalPort
                                    $Value = $Result.ProcessID
                                    $msg = "{0,-9}{1,-14}{2,-10}{3,-15}{4,-11}{5,-12}{6,-14}{7,-10}" -f  $Result.Protocol,$Result.LocalAddress,$Result.LocalPort,
                                                                                                         $Result.RemoteAddress,$Result.RemotePort,$Result.State,
                                                                                                         $Result.ProcessName,$Result.ProcessID
                                    if($Connections.$Key -eq $Value)
                                    {
                                        Write-Host $msg
                                    }
                                    else
                                    {
                                        $Connections.$Key = $Value
                                        Write-Host $msg -ForegroundColor Yellow
                                    }
                                }
                                if ($Host.UI.RawUI.KeyAvailable -and (3 -eq [int]$Host.UI.RawUI.ReadKey("AllowCtrlC,IncludeKeyUp,NoEcho").Character))
                                {
                                    Write-Host "Exiting now..." -foregroundcolor Yellow
                                    Write-Host
                                    [console]::TreatControlCAsInput = $false
                                    break
                                }
                                $Host.UI.RawUI.CursorPosition = $oldPos
                                start-sleep $Sleep
                            }
                        }
    }
}

#endregion 


#region Get-NetworkAddress 

function Get-NetworkAddress
{
        
    <#
        .Synopsis 
            Get the network address of a given lan segment.
            
        .Description
            Get the network address of a given lan segment.
                        
        .Parameter IP 
            IP address.
            
        .Parameter Mask 
            Subnet Mask for Network.
            
        .Parameter Binary 
            Switch to Return Binary
        
        .Example
            Get-NetworkAddress -IP 192.168.1.36 -mask 255.255.255.0
            Description
            -----------
            Returns the Network Address for given IP and Mask
                    
        .OUTPUTS
            System.String
            
        .INPUTS
            System.String
            
        .Link
            Get-IPRange
            Ping-Subnet
            Invoke-PingMonitor
            ConvertTo-BinaryIP 
            ConvertFrom-BinaryIP 
            ConvertTo-MaskLength 
            ConvertFrom-MaskLength 
            
        .Notes
            NAME:      Get-NetworkAddress
            AUTHOR:    Glenn Sizemore
            Website:   http://get-admin.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param (
        [Parameter(Mandatory=$true)]
        [string]$IP, 
        
        [Parameter(Mandatory=$true)]
        [string]$Mask, 
        
        [Parameter()]
        [switch]$Binary
    )
    Begin 
    {
    
        Write-Verbose " [Get-NetworkAddress] :: Begin "
        $NetAdd = $null
    
        $BinaryIP = ConvertTo-BinaryIP $IP
        $BinaryMask = ConvertTo-BinaryIP $Mask
    
        0..34 | %{
            $IPBit = $BinaryIP.Substring($_,1)
            $MaskBit = $BinaryMask.Substring($_,1)
            if ($IPBit -eq '1' -and $MaskBit -eq '1') 
            {
                $NetAdd = $NetAdd + "1"
            } 
            elseif ($IPBit -eq ".") 
            {
                $NetAdd = $NetAdd + '.'
            } 
            else 
            {
                $NetAdd = $NetAdd + "0"
            }
        }
        if ($Binary) 
        {
            return $NetAdd
        } 
        else 
        {
            return ConvertFrom-BinaryIP $NetAdd
        }
    
    }
}
    
#endregion 


#region Get-NetworkLocation 

function Get-NetworkLocation
{
        
    <#
        .Synopsis 
            Gets the network(s) on the host.
            
        .Description
            Gets the network(s) on the host.
            
        .Parameter Name
            Name of the Network (default to all.) Uses RegEX.
            
        .Example
            Get-NetworkLocation
            Description
            -----------
            Gets Network Location for all networks
        
        .Example
            Get-NetworkLocation -Name MyNetwork
            Description
            -----------
            Gets Network Location for MyNetwork
            
        .OUTPUTS
            PSCustomObject
            
        .Link
            Set-NetworkLocation
            
        .Notes
            NAME:      Get-NetworkLocation
            AUTHOR:    YetiCentral\bshell
            Website:   www.bsonposh.com
            LASTEDIT:  11/03/2009 
            #Requires -Version 2.0
    #>
        
    [Cmdletbinding()]
    Param(
        [Parameter()]
        [string]$Name = ".*"
    )
    
    function ConvertTo-NetworkLocation($CATEGORY)
        {
            switch ($CATEGORY)
            {
                0    {"Public"}
                1    {"Private"}
                2    {"Domain"}
            }
        }
        
    # Skip network location setting for pre-Vista operating systems 
    if([environment]::OSVersion.version.Major -lt 6) { return } 
    try
    {
        # Get network connections 
        $networkListManager = [Activator]::CreateInstance([Type]::GetTypeFromCLSID([Guid]"{DCB00C01-570F-4A9B-8D69-199FDBA5723B}")) 
        $connections = $networkListManager.GetNetworkConnections() | ?{$_.GetNetwork().GetName() -match $Name}
        
        # Get network location to Private for all networks 
        foreach($conn in $connections)
        {
            $myobj = @{}
            $myobj.Network = ($conn.GetNetwork().GetName()) 
            $myobj.Category = (ConvertTo-NetworkLocation ($conn.GetNetwork().GetCategory()))
    
            $obj = New-Object PSObject -Property $myobj
            $obj.PSTypeNames.Clear()
            $obj.PSTypeNames.Add('BSonPosh.NetworkLocation')
            $obj
        }
    }
    catch
    {
        Write-Host "ERROR: $($Error[0])" -ForegroundColor Red
    }
}
    
#endregion 


#region Get-NicInfo 

function Get-NICInfo
{

    <#
        .Synopsis  
            Gets the NIC info for specified host
            
        .Description
            Gets the NIC info for specified host
            
        .Parameter ComputerName
            Name of the Computer to get the NIC info from (Default is localhost.)
            
        .Example
            Get-NicInfo
            # Gets NIC info from local machine
    
        .Example
            Get-NicInfo -ComputerName MyServer
            Description
            -----------
            Gets NIC info from MyServer
            
        .Example
            $Servers | Get-NicInfo
            Description
            -----------
            Gets NIC info for each machine in the pipeline
            
        .OUTPUTS
            PSCustomObject
            
        .Notes
            NAME:      Get-NicInfo 
            AUTHOR:    YetiCentral\bshell
            Website:   www.bsonposh.com
            #Requires -Version 2.0
    #>
    
	[Cmdletbinding()]
	Param(
	    [alias('dnsHostName')]
		[Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
		[string]$ComputerName = $Env:COMPUTERNAME
	)

	Process
	{
		if($ComputerName -match "(.*)(\$)$")
		{
			$ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
		}
		
		if(Test-Host -ComputerName $ComputerName -TCPPort 135)
		{
			try
			{
				$NICS = Get-WmiObject -class Win32_NetworkAdapterConfiguration -ComputerName $ComputerName
				
				foreach($NIC in $NICS)
				{
					$Query = "Select Name,NetConnectionID FROM Win32_NetworkAdapter WHERE Index='$($NIC.Index)'"
					$NetConnnectionID = Get-WmiObject -Query $Query -ComputerName $ComputerName
					
					$myobj = @{
                        ComputerName = $ComputerName
						Name         = $NetConnnectionID.Name
						NetID        = $NetConnnectionID.NetConnectionID
						MacAddress   = $NIC.MacAddress
						IP           = $NIC.IPAddress | ?{$_ -match "\d*\.\d*\.\d*\."}
						Subnet       = $NIC.IPSubnet  | ?{$_ -match "\d*\.\d*\.\d*\."}
						Enabled      = $NIC.IPEnabled
						Index        = $NIC.Index
					}
					
					$obj = New-Object PSObject -Property $myobj
					$obj.PSTypeNames.Clear()
					$obj.PSTypeNames.Add('BSonPosh.NICInfo')
					$obj
				}
			}
			catch
			{
				Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
			}
		}
		else
		{
			Write-Host " Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
		}
	}
} 

#endregion 


#region Get-OSVersion 

function Get-OSVersion
{
        
    <#
        .Synopsis 
            Gets the OS Version for specified host.
            
        .Description
            Gets the OS Version for specified host.
            
        .Parameter ComputerName
            Name of the Computer to get the OS Version from (Default is localhost.)
            
        .Example
            Get-OSVersion
            Description
            -----------
            Gets OS Version from local machine
    
        .Example
            Get-OSVersion -ComputerName MyServer
            Description
            -----------
            Gets OS Version from MyServer
            
        .Example
            $Servers | Get-OSVersion
            Description
            -----------
            Gets OS Version for each machine in the pipeline
            
        .OUTPUTS
            PSCustomObject
            
        .INPUTS
            System.String
            
        .Link
            N/A
            
        .Notes
            NAME:      Get-OSVersion
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME
    )
    
    Process 
    {
    
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        if(Test-Host -ComputerName $ComputerName -TCPPort 135)
        {
            try
            {
                $OSInfo = Get-WmiObject Win32_OperatingSystem -ComputerName $ComputerName -ea STOP
                $myobj = @{}
                $myobj.ComputerName = $ComputerName
                $myobj.OSName = $OSInfo.Caption
                $myobj.OSVersion = $OSInfo.Version
                $myobj.ServicePack = $OSInfo.ServicePackMajorVersion
                
                $obj = New-Object PSObject -Property $myobj
                $obj.PSTypeNames.Clear()
                $obj.PSTypeNames.Add('BSonPosh.OSVersion')
                $obj
            }
            catch
            {
                Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
            }
        }
        else
        {
            Write-Host " Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
        }
    
    }
}
    
#endregion 


#region Get-ComputerSystem 

function Get-ComputerSystem
{
        
    <#
        .Synopsis 
            Gets the Computer System info for specified host.
            
        .Description
            Gets the Computer System info for specified host.
            
        .Parameter ComputerName
            Name of the Computer to get the Computer System info from (Default is localhost.)
            
        .Example
            Get-ComputerSystem
            Description
            -----------
            Gets Computer System info from local machine
    
        .Example
            Get-ComputerSystem -ComputerName MyServer
            Description
            -----------
            Gets Computer System info from MyServer
            
        .Example
            $Servers | Get-ComputerSystem
            Description
            -----------
            Gets Computer System info for each machine in the pipeline
            
        .OUTPUTS
            PSCustomObject
            
        .INPUTS
            System.String
            
        .Link
            N/A
            
        .Notes
            NAME:      Get-ComputerSystem
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME
    )
    
    Process 
    {
    
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        if(Test-Host -ComputerName $ComputerName -TCPPort 135)
        {
            try
            {
                $CompInfo = Get-WmiObject Win32_ComputerSystem -ComputerName $ComputerName -ea STOP
                $myobj = @{
                    ComputerName = $ComputerName
                    Manufacturer = $CompInfo.Manufacturer
                    Model        = $CompInfo.Model
                    RamMB        = [int]($CompInfo.TotalPhysicalMemory / 1mb)
                    CPUs         = $CompInfo.NumberOfProcessors
                    Cores        = $CompInfo.NumberOfLogicalProcessors
                }
                
                $obj = New-Object PSObject -Property $myobj
                $obj.PSTypeNames.Clear()
                $obj.PSTypeNames.Add('BSonPosh.Computer.System')
                $obj
            }
            catch
            {
                Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
            }
        }
        else
        {
            Write-Host " Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
        }
    
    }
}
    
#endregion # Get-ComputerSystem


#region Get-Environment 

function Get-Environment
{
        
    <#
        .Synopsis 
            Gets the Computer Environment info for specified host.
            
        .Description
            Gets the Computer Environment info for specified host.
            
        .Parameter ComputerName
            Name of the Computer to get the Computer Environment info from (Default is localhost.)
            
        .Parameter UserName
            Name of the User to get the Computer Environment info for.
            
        .Example
            Get-Environment
            Description
            -----------
            Gets Computer Environment info from local machine
    
        .Example
            Get-Environment -ComputerName MyServer
            Description
            -----------
            Gets Computer Environment info from MyServer
            
        .Example
            $Servers | Get-Environment
            Description
            -----------
            Gets Computer Environment info for each machine in the pipeline
            
        .Example
            Get-Environment -UserName BSonPosh
            Description
            -----------
            Gets Computer Environment info for User BSonPosh on local host.
            
        .Example
            Get-Environment -UserName BSonPosh -ComputerName MyServer
            Description
            -----------
            Gets Computer Environment info for User BSonPosh on MyServer.
            
        .OUTPUTS
            PSCustomObject
            
        .INPUTS
            System.String
            
        .Link
            N/A
            
        .Notes
            NAME:      Get-Environment
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME,
        
        [Parameter()]
        [string]$UserName = "%"
        
    )
    
    Process 
    {
    
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        if(Test-Host -ComputerName $ComputerName -TCPPort 135)
        {
            try
            {
                $Entries = Get-WmiObject -Query "Select * FROM Win32_Environment WHERE UserName LIKE '%${UserName}%'" -ComputerName $ComputerName -ea STOP
                foreach($Entry in $Entries)
                {
                    $myobj = @{
                        ComputerName = $ComputerName
                        Name         = $Entry.Name
                        Value        = $Entry.VariableValue
                        UserName     = $Entry.UserName
                    }
                    $obj = New-Object PSObject -Property $myobj
                    $obj.PSTypeNames.Clear()
                    $obj.PSTypeNames.Add('BSonPosh.Computer.Environment')
                    $obj
                }
            }
            catch
            {
                Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
            }
        }
        else
        {
            Write-Host " Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
        }
    
    }
}
    
#endregion # Get-Environment


#region Get-NetworkConnection

function Get-NetworkConnection
{
        
    <#
        .Synopsis 
            Gets the Computer Network Connection info for specified host.(Only works locally)
            
        .Description
            Gets the Computer Network Connection info for specified host.(Only works locally)
            
        .Example
            Get-NetworkConnection
            Description
            -----------
            Gets Computer Network Connection info from local machine
    
        .OUTPUTS
            PSCustomObject
            
        .INPUTS
            System.String
            
        .Link
            N/A
            
        .Notes
            NAME:      Get-NetworkConnection
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
    
    )
    
    Process 
    {
        try
        {
            $Entries = Get-WmiObject Win32_NetworkConnection -ea STOP
            foreach($Entry in $Entries)
            {
                $myobj = @{
                    Name         = $Entry.LocalName
                    UNC          = $Entry.RemoteName
                    State        = $Entry.ConnectionState
                    Status       = $Entry.Status
                }
                $obj = New-Object PSObject -Property $myobj
                $obj.PSTypeNames.Clear()
                $obj.PSTypeNames.Add('BSonPosh.Computer.NetworkConnection')
                $obj
            }
        }
        catch
        {
            Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
        }
    }
}
    
#endregion # Get-NetworkConnection


#region Get-OperatingSystem

function Get-OperatingSystem
{
        
    <#
        .Synopsis 
            Gets the Operating System info for specified host.
            
        .Description
            Gets the Operating System info for specified host.
            
        .Parameter ComputerName
            Name of the Computer to get the Operating System info from (Default is localhost.) 
            
        .Example
            Get-OperatingSystem
            Description
            -----------
            Gets Operating System info from local machine
    
        .Example
            Get-OperatingSystem -ComputerName MyOtherDesktop
            Description
            -----------
            Gets Operating System info from MyOtherDesktop
            
        .Example
            $Windows7Machines | Get-OperatingSystem
            Description
            -----------
            Gets Operating System info for each machine in the pipeline
            
        .OUTPUTS
            PSCustomObject
            
        .INPUTS
            System.String
            
        .Link
            N/A
            
        .Notes
            NAME:      Get-OperatingSystem
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME
    )
    
    Process 
    {
    
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        if(Test-Host -ComputerName $ComputerName -TCPPort 135)
        {
            try
            {
                $OSInfo = Get-WmiObject Win32_OperatingSystem -ComputerName $ComputerName -ea STOP
                $myobj = @{
                    ComputerName     = $ComputerName
                    Name             = $OSInfo.Caption
                    Version          = $OSInfo.Version
                    OSArchitecture   = $OSInfo.OSArchitecture
                    WindowsDirectory = $OSInfo.WindowsDirectory
                    SystemDirectory  = $OSInfo.SystemDirectory
                    SystemDrive      = $OSInfo.SystemDrive
                    LocalTime        = $OSInfo.ConvertToDateTime($OSInfo.LocalDateTime)
                 }
                
                $obj = New-Object PSObject -Property $myobj
                $obj.PSTypeNames.Clear()
                $obj.PSTypeNames.Add('BSonPosh.Computer.OS')
                $obj
            }
            catch
            {
                Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
            }
        }
        else
        {
            Write-Host " Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
        }
    
    }
}
    
#endregion # Get-OperatingSystem


#region Get-Bios

function Get-Bios
{
        
    <#
        .Synopsis 
            Gets the Computer BIOS info for specified host.
            
        .Description
            Gets the Computer BIOS info for specified host.
            
        .Parameter ComputerName
            Name of the Computer to get the Computer BIOS info from (Default is localhost.)
            
        .Example
            Get-Bios
            Description
            -----------
            Gets Computer BIOS info from local machine
    
        .Example
            Get-Bios -ComputerName MyServer
            Description
            -----------
            Gets Computer BIOS info from MyServer
            
        .Example
            $Servers | Get-Bios
            Description
            -----------
            Gets Computer BIOS info for each machine in the pipeline
            
        .OUTPUTS
            PSCustomObject
            
        .INPUTS
            System.String
            
        .Link
            N/A
            
        .Notes
            NAME:      Get-Bios
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME
    )
    
    Process 
    {
    
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        if(Test-Host -ComputerName $ComputerName -TCPPort 135)
        {
            try
            {
                $BIOSInfo = Get-WmiObject Win32_BIOS -ComputerName $ComputerName -ea STOP
                $myobj = @{
                    ComputerName = $ComputerName
                    Manufacturer = $BIOSInfo.Manufacturer
                    SerialNumber = $BIOSInfo.SerialNumber
                    Name         = $BIOSInfo.Description
                    Version      = $BIOSInfo.SMBIOSBIOSVersion
                    ReleaseDate  = [datetime]::ParseExact($BIOSInfo.ReleaseDate.Split(".")[0],"yyyyMMddhhmmss",$null)
                }
                
                $obj = New-Object PSObject -Property $myobj
                $obj.PSTypeNames.Clear()
                $obj.PSTypeNames.Add('BSonPosh.Computer.BIOS')
                $obj
            }
            catch
            {
                Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
            }
        }
        else
        {
            Write-Host " Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
        }
    
    }
}
    
#endregion # Get-Bios


#region Get-WindowsExperienceIndex

function Get-WindowsExperienceIndex
{
        
    <#
        .Synopsis 
            Gets the Windows Experience Index info for specified host. Windows 7 Only!
            
        .Description
            Gets the Windows Experience Index info for specified host. Windows 7 Only!
            
        .Parameter ComputerName
            Name of the Computer to get the Windows Experience Index info from (Default is localhost.) 
            
        .Example
            Get-WindowsExperienceIndex
            Description
            -----------
            Gets Windows Experience Index from local machine
    
        .Example
            Get-WindowsExperienceIndex -ComputerName MyOtherDesktop
            Description
            -----------
            Gets Windows Experience Index from MyOtherDesktop
            
        .Example
            $Windows7Machines | Get-WindowsExperienceIndex
            Description
            -----------
            Gets Windows Experience Index for each machine in the pipeline
            
        .OUTPUTS
            PSCustomObject
            
        .INPUTS
            System.String
            
        .Link
            N/A
            
        .Notes
            NAME:      Get-WindowsExperienceIndex
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME
    )
    
    Process 
    {
    
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        if(Test-Host -ComputerName $ComputerName -TCPPort 135)
        {
            try
            {
                $WinSAT = Get-WmiObject Win32_WinSat -ComputerName $ComputerName -ea STOP
                $myobj = @{
                    ComputerName = $ComputerName
                    CPU          = $WinSAT.GraphicsScore
                    Gaming       = $WinSAT.D3DScore
                    Graphics     = $WinSAT.GraphicsScore
                    HardDisk     = $WinSAT.DiskScore
                    Memory       = $WinSAT.MemoryScore
                    Base         = $WinSAT.WinSPRLevel
                 }
                
                $obj = New-Object PSObject -Property $myobj
                $obj.PSTypeNames.Clear()
                $obj.PSTypeNames.Add('BSonPosh.Computer.WinSAT')
                $obj
            }
            catch
            {
                Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
            }
        }
        else
        {
            Write-Host " Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
        }
    
    }
}
    
#endregion # Get-WindowsExperienceIndex


#region Get-MotherBoard

function Get-MotherBoard
{
        
    <#
        .Synopsis 
            Gets the Mother Board info for specified host.
            
        .Description
            Gets the Mother Board info for specified host.
            
        .Parameter ComputerName
            Name of the Computer to get the Mother Board info from (Default is localhost.) 
            
        .Example
            Get-MotherBoard
            Description
            -----------
            Gets Mother Board info from local machine
    
        .Example
            Get-MotherBoard -ComputerName MyOtherDesktop
            Description
            -----------
            Gets Mother Board info from MyOtherDesktop
            
        .Example
            $Windows7Machines | Get-MotherBoard
            Description
            -----------
            Gets Mother Board info for each machine in the pipeline
            
        .OUTPUTS
            PSCustomObject
            
        .INPUTS
            System.String
            
        .Link
            N/A
            
        .Notes
            NAME:      Get-MotherBoard
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME
    )
    
    Process 
    {
    
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        if(Test-Host -ComputerName $ComputerName -TCPPort 135)
        {
            try
            {
                $MBInfo = Get-WmiObject Win32_BaseBoard -ComputerName $ComputerName -ea STOP
                $myobj = @{
                    ComputerName     = $ComputerName
                    Name             = $MBInfo.Product
                    Manufacturer     = $MBInfo.Manufacturer
                    Version          = $MBInfo.Version
                    SerialNumber     = $MBInfo.SerialNumber
                 }
                
                $obj = New-Object PSObject -Property $myobj
                $obj.PSTypeNames.Clear()
                $obj.PSTypeNames.Add('BSonPosh.Computer.MotherBoard')
                $obj
            }
            catch
            {
                Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
            }
        }
        else
        {
            Write-Host " Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
        }
    
    }
}
    
#endregion # Get-MotherBoard


#region Get-ComputerDomainInfo

function Get-ComputerDomainInfo
{
        
    <#
        .Synopsis 
            Gets the Domain info for specified host.
            
        .Description
            Gets the Domain info for specified host.
            
        .Parameter ComputerName
            Name of the Computer to get the Domain info from (Default is localhost.) 
            
        .Example
            Get-ComputerDomainInfo
            Description
            -----------
            Gets Domain info from local machine
    
        .Example
            Get-ComputerDomainInfo -ComputerName MyOtherDesktop
            Description
            -----------
            Gets Domain info from MyOtherDesktop
            
        .Example
            $Windows7Machines | Get-ComputerDomainInfo
            Description
            -----------
            Gets Domain info for each machine in the pipeline
            
        .OUTPUTS
            PSCustomObject
            
        .INPUTS
            System.String
            
        .Link
            N/A
            
        .Notes
            NAME:      Get-ComputerDomainInfo
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME
    )
    
    Process 
    {
    
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        if(Test-Host -ComputerName $ComputerName -TCPPort 135)
        {
            try
            {
                $Domains = Get-WmiObject Win32_NTDomain -ComputerName $ComputerName -Filter "Status='OK'" -ea STOP
                foreach($Domain in $Domains)
                {
                    $myobj = @{
                        ComputerName    = $ComputerName
                        Domain          = $Domain.Description
                        Forest          = $Domain.DnsForestName
                        ClientSite      = $Domain.ClientSiteName
                        DCSite          = $Domain.DcSiteName
                        CurrentDC       = $Domain.DomainControllerName
                    }
                    
                    $obj = New-Object PSObject -Property $myobj
                    $obj.PSTypeNames.Clear()
                    $obj.PSTypeNames.Add('BSonPosh.Computer.DomainInfo')
                    $obj
                }
            }
            catch
            {
                Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
            }
        }
        else
        {
            Write-Host " Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
        }
    
    }
}
    
#endregion # Get-ComputerDomainInfo


#region Get-RemoteSession

function Get-RemoteSession
{
        
    <#
        .Synopsis 
            Gets the Remote Session info for specified host. Only remote!
            
        .Description
            Gets the Remote Session info for specified host. Only remote!
            
        .Parameter ComputerName
            Name of the Computer to get the Remote Session info from (Default is localhost.) 
            
        .Example
            Get-RemoteSession
            Description
            -----------
            Gets Remote Session info from local machine
    
        .Example
            Get-RemoteSession -ComputerName MyOtherDesktop
            Description
            -----------
            Gets Remote Session info from MyOtherDesktop
            
        .Example
            $Windows7Machines | Get-RemoteSession
            Description
            -----------
            Gets Remote Session info for each machine in the pipeline
            
        .OUTPUTS
            PSCustomObject
            
        .INPUTS
            System.String
            
        .Link
            N/A
            
        .Notes
            NAME:      Get-RemoteSession
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME
    )
    
    Process 
    {
    
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        if(Test-Host -ComputerName $ComputerName -TCPPort 135)
        {
            try
            {
                $Sessions = Get-WmiObject Win32_ServerSession -ComputerName $ComputerName -ea STOP
                foreach($Session in $Sessions)
                {
                    $myobj = @{
                        ComputerName    = $ComputerName
                        UserName        = $Session.UserName
                        ClientName      = $Session.ComputerName
                        IdleTime        = $Session.IdleTime
                        ActiveTime      = $Session.ActiveTime
                        Resources       = $Session.ResourcesOpened
                    }
                    
                    $obj = New-Object PSObject -Property $myobj
                    $obj.PSTypeNames.Clear()
                    $obj.PSTypeNames.Add('BSonPosh.Computer.RemoteSessionInfo')
                    $obj
                }
            }
            catch
            {
                Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
            }
        }
        else
        {
            Write-Host " Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
        }
    
    }
}
    
#endregion # Get-RemoteSession


#region Get-RebootTime 

function Get-RebootTime
{
        
    <#
        .Synopsis 
            Gets the reboot time for specified host.
            
        .Description
            Gets the reboot time for specified host.
            
        .Parameter ComputerName
            Name of the Computer to get the reboot time from (Default is localhost.)
            
        .Example
            Get-RebootTime
            Description
            -----------
            Gets OS Version from local     
        
        .Example
            Get-RebootTime -Last
            Description
            -----------
            Gets last reboot time from local machine
            
        
    
        .Example
            Get-RebootTime -ComputerName MyServer
            Description
            -----------
            Gets reboot time from MyServer
            
        .Example
            $Servers | Get-RebootTime
            Description
            -----------
            Gets reboot time for each machine in the pipeline
            
        .OUTPUTS
            PSCustomObject
            
        .INPUTS
            System.String
            
        .Link
            N/A
            
        .Notes
            NAME:      Get-RebootTime
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [cmdletbinding()]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME,
        
        [Parameter()]
        [Switch]$Last
    )
    process 
    {
    
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        if(Test-Host $ComputerName -TCPPort 135)
        {
            try
            {
                if($Last)
                {
                    $date = Get-WmiObject Win32_OperatingSystem -ComputerName $ComputerName -ea STOP | foreach{$_.LastBootUpTime}
                    $RebootTime = [System.DateTime]::ParseExact($date.split('.')[0],'yyyyMMddHHmmss',$null)
                    $myobj = @{}
                    $myobj.ComputerName = $ComputerName
                    $myobj.RebootTime = $RebootTime
                    
                    $obj = New-Object PSObject -Property $myobj
                    $obj.PSTypeNames.Clear()
                    $obj.PSTypeNames.Add('BSonPosh.RebootTime')
                    $obj
                }
                else
                {
                    $Query = "Select * FROM Win32_NTLogEvent WHERE SourceName='eventlog' AND EventCode='6009'"
                    Get-WmiObject -Query $Query -ea 0 -ComputerName $ComputerName | foreach {
                        $myobj = @{}
                        $RebootTime = [DateTime]::ParseExact($_.TimeGenerated.Split(".")[0],'yyyyMMddHHmmss',$null)
                        $myobj.ComputerName = $ComputerName
                        $myobj.RebootTime = $RebootTime
                        
                        $obj = New-Object PSObject -Property $myobj
                        $obj.PSTypeNames.Clear()
                        $obj.PSTypeNames.Add('BSonPosh.RebootTime')
                        $obj
                    }
                }
    
            }
            catch
            {
                Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
            }
        }
        else
        {
            Write-Host " Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
        }
    
    }
}
    
#endregion 


#region Get-Routetable 

function Get-Routetable
{
    
    <#
        .Synopsis 
            Gets the route table for specified host.
            
        .Description
            Gets the route table for specified host.
            
        .Parameter ComputerName
            Name of the Computer to get the route table from (Default is localhost.)
            
        .Example
            Get-RouteTable
            Description
            -----------
            Gets route table from local machine
    
        .Example
            Get-RouteTable -ComputerName MyServer
            Description
            -----------
            Gets route table from MyServer
            
        .Example
            $Servers | Get-RouteTable
            Description
            -----------
            Gets route table for each machine in the pipeline
            
        .OUTPUTS
            PSCustomObject
            
        .INPUTS
            System.String
            
        .Link
            N/A
            
        .Notes
            NAME:      Get-RouteTable
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME
    )
    process 
    {
    
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        if(Test-Host $ComputerName -TCPPort 135)
        {
            $Routes = Get-WMIObject Win32_IP4RouteTable -ComputerName $ComputerName -Property Name,Mask,NextHop,Metric1,Type
            foreach($Route in $Routes)
            {
                $myobj = @{}
                $myobj.ComputerName = $ComputerName
                $myobj.Name = $Route.Name
                $myobj.NetworkMask = $Route.mask
                $myobj.Gateway = if($Route.NextHop -eq "0.0.0.0"){"On-Link"}else{$Route.NextHop}
                $myobj.Metric = $Route.Metric1
                
                $obj = New-Object PSObject -Property $myobj
                $obj.PSTypeNames.Clear()
                $obj.PSTypeNames.Add('BSonPosh.RouteTable')
                $obj
            }
        }
        else
        {
            Write-Host " Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
        }
    
    }
}
    
#endregion 


#region Get-SysInternals 

function Get-SysInternals
{
    
    <#
        .Synopsis 
            List or updates sysinternal files from the internet
            
        .Description
            List or updates sysinternal files from the internet
            
        .Parameter Path
            Where you want the files to download to.
            
        .Parameter FileName
            The FileName you want to download
            
        .Parameter All
            Updates all the Files
            
        .Parameter Passthru
            Returns a FileInfo Object for the downloaded file
            
        .Example
            Get-SysInternals
            Description
            -----------
            To see a list of available files from Sysinternals
            
        .Example 
            Get-SysInternals -FileName pslist.exe
            Description
            -----------
            To download a single file
            
        .Example
            Get-SysInternals -All
            Description
            -----------
            To download all the files available
            
        .Example 
            Get-ChildItem C:\tools | Get-SysInternals
            Description
            -----------
            To download only files you already have
            
        .OUTPUTS
            Object
            
        .Link
            N/A
            
        .Notes
            NAME:      Get-SysInternals
            AUTHOR:    YetiCentral\bshell
            Website:   www.bsonposh.com
            LASTEDIT:  03/16/2009 18:25:15
            #Requires -Version 2.0
    #>
    
    [cmdletbinding()]
    Param(
        [parameter()]
        $Path,
        [parameter(ValueFromPipeLine=$true)]
        $FileName,
        [parameter()]
        [switch]$All,
        [parameter()]
        [switch]$Passthru
    )
    
    Begin 
    {
    
        if(!$Path)
        {
            $CommandPath = (Get-command pslist.exe -ErrorAction 0).Path
            if($CommandPath -and (Test-Path $CommandPath))
            {
                $path = split-path $CommandPath -parent -ErrorAction 0
            }
            else
            {
                $path = Read-Host "Enter Path"
            }
        }
        
        Write-Verbose " Path: $Path"
        Write-Verbose " FileName: $FileName"
        write-verbose " ALL: $ALL"
        $Cont = $true
        
    }
    
    Process 
    {
    
        if($FileName)
        {
            Try
            {
                Write-Verbose " Downloading File [$FileName]"
                $webclient.DownloadFile("http://live.sysinternals.com/$FileName","$path\$FileName")
                Write-Verbose " ==> Downloaded [$FileName]"
                if($passthru){Get-Item "$path\$FileName"}
            }
            catch
            {
                Write-Verbose " Failed to Download File [$FileName]"
            }
            $cont = $false
        }
    
    }
    
    End 
    {
    
        if($Cont)
        {
            # Get file content
            $webclient = New-Object System.Net.WebClient
            $HTML = $webclient.DownloadString("http://live.sysinternals.com/") 
            $links = $HTML -split "<br>"
            $Files = @()
            
            # Building RegEx
            $regex = "^.*y,\s(?<DATE>.*)(AM|PM)"
            $regex += "\s*(?<Length>\d*)\s+\"
            $regex += "<A HREF=\`"/.*\`">(?<filename>.*)\</A\>"
            
            # Creating an Object from the Links
            switch -regex ($links)
            {
                $regex
                { 
                    $myobj = "" | Select FileName,Date,Length
                    $myobj.FileName += $matches.FileName
                    $myobj.Date = get-date $matches.Date
                    $myobj.Length = $matches.Length
                    $files += $myobj         
                }
            }
            
            if($All)
            {
                foreach($file in $files)
                {
                    $FileName = $file.FileName
                    Try
                    {
                        Write-Verbose " Downloading File [$FileName] to [$Path]"
                        $webclient.DownloadFile("http://live.sysinternals.com/$FileName","$path\$FileName")
                        Write-Verbose " ==> Downloaded [$FileName]"
                        if($passthru){Get-Item "$path\$FileName"}
                    }
                    catch
                    {
                        Write-Verbose " Failed to Download File [$File]"
                    }
                }
            }
            else
            {
                $files
            }
        }
    
    }

}

#endregion 


#region Get-SystemType 

function Get-SystemType
{
        
    <#
        .Synopsis 
            Gets the system type for specified host
            
        .Description
            Gets the system type info for specified host
            
        .Parameter ComputerName
            Name of the Computer to get the System Type from (Default is localhost.)
            
        .Example
            Get-SystemType
            Description
            -----------
            Gets System Type from local machine
    
        .Example
            Get-SystemType -ComputerName MyServer
            Description
            -----------
            Gets System Type from MyServer
            
        .Example
            $Servers | Get-SystemType
            Description
            -----------
            Gets System Type for each machine in the pipeline
            
        .OUTPUTS
            PSObject
            
        .Notes
            NAME:      Get-SystemType 
            AUTHOR:    YetiCentral\bshell
            Website:   www.bsonposh.com
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME
    )
    
    Begin 
    {
    
        function ConvertTo-ChassisType($Type)
        {
            switch ($Type)
            {
                1    {"Other"}
                2    {"Unknown"}
                3    {"Desktop"}
                4    {"Low Profile Desktop"}
                5    {"Pizza Box"}
                6    {"Mini Tower"}
                7    {"Tower"}
                8    {"Portable"}
                9    {"Laptop"}
                10    {"Notebook"}
                11    {"Hand Held"}
                12    {"Docking Station"}
                13    {"All in One"}
                14    {"Sub Notebook"}
                15    {"Space-Saving"}
                16    {"Lunch Box"}
                17    {"Main System Chassis"}
                18    {"Expansion Chassis"}
                19    {"SubChassis"}
                20    {"Bus Expansion Chassis"}
                21    {"Peripheral Chassis"}
                22    {"Storage Chassis"}
                23    {"Rack Mount Chassis"}
                24    {"Sealed-Case PC"}
            }
        }
        function ConvertTo-SecurityStatus($Status)
        {
            switch ($Status)
            {
                1    {"Other"}
                2    {"Unknown"}
                3    {"None"}
                4    {"External Interface Locked Out"}
                5    {"External Interface Enabled"}
            }
        }
    
    }
    Process 
    {
    
        Write-Verbose " [Get-SystemType] :: Process Start"
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        if(Test-Host $ComputerName -TCPPort 135)
        {
            try
            {
                Write-Verbose " [Get-SystemType] :: Getting System (Enclosure) Type info use WMI"
                $SystemInfo = Get-WmiObject Win32_SystemEnclosure -ComputerName $ComputerName
                $CSInfo = Get-WmiObject -Query "Select Model FROM Win32_ComputerSystem" -ComputerName $ComputerName
                
                Write-Verbose " [Get-SystemType] :: Creating Hash Table"
                $myobj = @{}
                Write-Verbose " [Get-SystemType] :: Setting ComputerName   - $ComputerName"
                $myobj.ComputerName = $ComputerName
                
                Write-Verbose " [Get-SystemType] :: Setting Manufacturer   - $($SystemInfo.Manufacturer)"
                $myobj.Manufacturer = $SystemInfo.Manufacturer
                
                Write-Verbose " [Get-SystemType] :: Setting Module   - $($CSInfo.Model)"
                $myobj.Model = $CSInfo.Model
                
                Write-Verbose " [Get-SystemType] :: Setting SerialNumber   - $($SystemInfo.SerialNumber)"
                $myobj.SerialNumber = $SystemInfo.SerialNumber
                
                Write-Verbose " [Get-SystemType] :: Setting SecurityStatus - $($SystemInfo.SecurityStatus)"
                $myobj.SecurityStatus = ConvertTo-SecurityStatus $SystemInfo.SecurityStatus
                
                Write-Verbose " [Get-SystemType] :: Setting Type           - $($SystemInfo.ChassisTypes)"
                $myobj.Type = ConvertTo-ChassisType $SystemInfo.ChassisTypes
                
                Write-Verbose " [Get-SystemType] :: Creating Custom Object"
                $obj = New-Object PSCustomObject -Property $myobj
                $obj.PSTypeNames.Clear()
                $obj.PSTypeNames.Add('BSonPosh.SystemType')
                $obj
            }
            catch
            {
                Write-Verbose " [Get-SystemType] :: [$ComputerName] Failed with Error: $($Error[0])" 
            }
        }
    
    }
    
}
    
#endregion 


#region Get-TraceFile 

function Get-TraceFile
{
        
    <#
        .Synopsis
            Gets Data from a tracelog.exe using tracerpt.exe
        
        .Description
            Gets Data from a tracelog.exe using tracerpt.exe
            
        .Parameter Source
            The Tracelog file to convert (.etl) Default $pwd\Logfile.etl
        
        .Parameter File
            The name of the CSV file to Export to. Default TraceResults.csv.
        
        .Parameter CSV 
            [SWITCH] :: Returns the file created
            
        .Example
            Get-TraceFile
            Description
            -----------
            Gets a tracefile called $pwd\LogFile.Etl
        
        .Example
            Get-TraceFile -Source C:\temp\MyLogFile.Etl
            Description
            -----------
            Gets a tracefile called C:\temp\MyLogFile.Etl
            
        .OUTPUTS
            PSCustomObject
    
        .Notes
            NAME:      Test-LDAPFilter
            AUTHOR:    YetiCentral\bshell
            Website:   www.bsonposh.com
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
    
        [parameter()]
        $Source="$pwd\LogFile.Etl",
        
        [parameter()]
        $file="$pwd\TraceResults.csv",
        
        [parameter()]
        [switch]$csv
        
    )
    
    if(Test-Path $pwd\tracelog.exe)
    {
        $tracerpt = "$pwd\tracerpt.exe"
    }
    elseif(get-command tracelog.exe)
    {
        $tracerpt = "tracerpt.exe"
    }
    else
    {
        throw "Missing tracerpt.exe"
        return 1
    }
    
    
    $cmd = "$tracerpt $Source -o $file -of CSV"
    
    invoke-Expression $cmd
    
    if($csv)
    {
        Write-Host "CSV File [ $file ] Created!"
        get-chiditem $file
    }
    else
    {
        import-csv $file
    }
}
    
#endregion 


#region Get-Uptime 

function Get-Uptime
{
        
    <#
        .Synopsis 
            Gets the Uptime for the target machine.
            
        .Description
            Gets the Uptime for the target machine.
            
        .Parameter ComputerName
            Target to the Get-Uptime Command
            
        .Example
            Get-Uptime -ComputerName MyPC
            Description
            -----------
            Gets uptimne for MyPC
            
        .Example
            $Serverse | Get-Uptime 
            Description
            -----------
            Gets uptime for all the servers in the pipeline
    
        .OUTPUTS
            PSCustomObject
            
        .INPUTS
            System.String
            
        .Notes
            NAME:      Get-Uptime
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [cmdletbinding()]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME
    )
    
    Process 
    {
    
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        if(Test-Host $ComputerName -TCPPort 135)
        {
            try
            {
                $os = Get-WmiObject Win32_OperatingSystem -ComputerName $ComputerName -Property LastBootUpTime,LocalDateTime -ea STOP
                $uptime = $OS.ConvertToDateTime($os.LastBootUpTime)
                $RemoteTime = $OS.ConvertToDateTime($os.LocalDateTime)
                $timespan = $RemoteTime - $Uptime
                
                $myobj = @{}
                $myobj.ComputerName = $ComputerName
                $myobj.Uptime  = "\\$ComputerName has been up for: $($timespan.days) days, $($timespan.Hours) hours, $($timespan.Minutes) minutes, $($timespan.seconds) seconds"
                $myobj.Days    = $timespan.days
                $myobj.Hours   = $timespan.hours
                $myobj.Minutes = $timespan.minutes
                $myobj.Seconds = $timespan.Seconds
                
                $obj = New-Object PSObject -Property $myobj
                $obj.PSTypeNames.Clear()
                $obj.PSTypeNames.Add('BSonPosh.UPtime')
                $obj
            }
            catch
            {
                Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
            }
        }
        else
        {
            Write-Host " Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
        }
    
    }
}
    
#endregion 


#region Get-WindowsUpdate 

function Get-WindowsUpdate
{
        
    <#
        .Synopsis  
            Invokes Windows Update on local machine.
            
        .Description
            Invokes Windows Update on local machine.
            
        .Parameter Download
            [Switch] :: Download only
            
        .Parameter Install
            [Switch] :: Install
            
        .Parameter FullDetail
            [Switch] :: Provide Full Detail
            
        .Parameter Confirm
            [Switch] :: Prompt for Confirmation
                
        .Example
            Get-WindowsUpdate
            Description
            -----------
            Gets all the Windows updates for the local machine
            
        .Example
            Get-WindowsUpdate -download
            Description
            -----------
            Downloads all the Windows updates for the local machine
            
        .Example
            Get-WindowsUpdate -Install
            Description
            -----------
            Installs all the Windows updates for the local machine
            
        .Example
            Get-WindowsUpdate -Confirm
            Description
            -----------
            Gets all the Windows updates for the local machine prompting before installing.
            
        .OUTPUTS
            $null
            
        .INPUTS
            $null
            
        .Notes
            NAME:      Get-WindowsUpdate
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [Parameter()]
        [switch]$download,
        [Parameter()]
        [Switch]$install,
        [Parameter()]
        [switch]$FullDetail,
        [Parameter()]
        [switch]$confirm
    )
    
    function Get-WIAStatusValue($value)
    {
    switch -exact ($value)
        {
            0   {"NotStarted"}
            1   {"InProgress"}
            2   {"Succeeded"}
            3   {"SucceededWithErrors"}
            4   {"Failed"}
            5   {"Aborted"}
        
        } 
    } 
    
    Write-Host " - Creating WU COM object"
    $UpdateSession = New-Object -ComObject Microsoft.Update.Session
    $UpdateSearcher = $UpdateSession.CreateUpdateSearcher() 
    
    Write-Host " - Searching for Updates"
    $SearchResult = $UpdateSearcher.Search("IsAssigned=1 and IsHidden=0 and IsInstalled=0")
    if($Download -or $Install -or $Confirm)
    {
        Write-Host " - Found [$($SearchResult.Updates.count)] Updates to Download."
        
        # Get Total Download size    
        $Total = ($SearchResult.Updates | measure-Object -sum MaxDownloadSize).Sum    
        $Current = 0
        
        Write-Host (" - Total of {0:n2} MB to Download." -f ($Total/1mb))   
        Write-Host      
        foreach($Update in $SearchResult.Updates)    
        {        
            write-progress $Update.Title "Total Progress->" -percentcomplete ($Current/$Total*100)        
            $Size = "{0:n2}MB" -f ($Update.MaxDownloadSize/1mb)        
            if($Confirm)        
            {            
                $caption = "Get-WindowsUpdate: $($Update.Title) [$Size]"            
                $message = "Download/Install Update?"            
                $yes = new-Object System.Management.Automation.Host.ChoiceDescription "&Yes;"            
                $no = new-Object System.Management.Automation.Host.ChoiceDescription "&No;"            
                $choices = [System.Management.Automation.Host.ChoiceDescription[]]($yes,$no)            
                $answer = $host.ui.PromptForChoice($caption,$message,$choices,0)            
                if($answer -eq 1){$Current += $Update.MaxDownloadSize;continue}        
            }         
            
            # Check for Eula and Accept in needed        
            if ( $Update.EulaAccepted -eq 0 ) { $Update.AcceptEula() }        
            
            # Add Update to Collection         
            $UpdatesCollection = New-Object -ComObject Microsoft.Update.UpdateColl        
            $UpdatesCollection.Add($Update) | out-null
                
            # Download        
            Write-Host " + Downloading Update $($Update.Title) [$Size]"        
            $UpdatesDownloader = $UpdateSession.CreateUpdateDownloader()        
            $UpdatesDownloader.Updates = $UpdatesCollection        
            $DownloadResult = $UpdatesDownloader.Download()        
            $Message = "   - Download {0}" -f (Get-WIAStatusValue $DownloadResult.ResultCode)        
            Write-Host $message            
            
            # Install        
            if($install)        
            {            
                Write-Host "   - Installing Update"            
                $UpdatesInstaller = $UpdateSession.CreateUpdateInstaller()            
                $UpdatesInstaller.Updates = $UpdatesCollection            
                $InstallResult = $UpdatesInstaller.Install()            
                $Message = "   - Install {0}" -f (Get-WIAStatusValue $DownloadResult.ResultCode)            
                Write-Host $message            
                Write-Host        
            }        
            $Current += $Update.MaxDownloadSize    
        }
    }
    else
    {    
        Write-Host " - Found [$($SearchResult.Updates.count)] Updates."    
        Write-Host (" - Total of {0:n2} MB to Download." -f ($Total/1mb))    
        Write-Host    
        if($FullDetail)    
        {        
            $SearchResult.Updates       
        }    
        else    
        {        
            $SearchResult.Updates | %{$_.Title}    
        }
    }
}
    
#endregion 


#region Import-Credential 

function Import-Credential
{
    
    <#
        .Synopsis 
            Imports the PSCredential securely from a file.
            
        .Description
            Imports the PSCredential securely from a file.
            
        .Parameter File
            File to Import from.
            
        .Parameter RequirePassword
            [Switch] :: If passed a password is request to decrypt with.
        
        .Example
            Import-Credential -file c:\temp\mycred.pwf
            Description
            -----------
            Extracts the PSCredential object from c:\temp\mycred.pwf
    
        .OUTPUTS
            PSCredential
            
        .INPUTS
            System.String
            
        .Link
            Export-Credential
    
        .Notes
            NAME:      Import-Credential
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [cmdletbinding()]
    Param(
        [Parameter(Mandatory=$true)]
        [string]$File,
        [Parameter()]
        [Switch]$RequirePassword
    )
    
    function GetSecurePass ($SecurePassword) 
    {
        $Ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($SecurePassword)
        $password = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($Ptr)
        [System.Runtime.InteropServices.Marshal]::ZeroFreeCoTaskMemUnicode($Ptr)
        $password
    }
        
    $MyCredentialObject = Import-Clixml -Path $File
    $user = $MyCredentialObject.UserName
    $SecurePassword = $MyCredentialObject.Password
    
    if($RequirePassword)
    {
        $spwd = Read-Host -prompt "Enter Password to decrypt With" -asSecureString
        # Creating the Key for ConvertFrom-SecureString
        $ByteArrayforPassword = [System.Text.Encoding]::Unicode.GetBytes((GetSecurePass $spwd))
        if($ByteArrayforPassword.count -gt 24)
        {
            $key = @()
            [system.Array]::Copy($ByteArrayforPassword,$Key,24)
        }
        else
        {
            $key = $ByteArrayforPassword
            while($key.count -lt 24){$key += [byte]"11"}
        }
        $password = $SecurePassword | convertTo-SecureString -key $key
        $credential = New-Object System.Management.Automation.PsCredential($user,$password)
        $credential
    }
    else
    {
        $password = $SecurePassword | convertTo-SecureString
        $credential = New-Object System.Management.Automation.PsCredential($user,$password)
        $credential
    }
}
    
#endregion 


#region Invoke-PingMonitor 

function Invoke-PingMonitor
{
    
    <#
        .Synopsis
            Starts ping monitor for a Computer(s) or by network.
            
        .Description
            Starts ping monitor for a Computer(s) or by network.
                        
        .Parameter ComputerName 
            Name of the Computer.
            
        .Parameter Network 
            Network Address.
        
        .Example
            Invoke-Pingmonitor -ComputerName MyComputer
            Description
            -----------
            Starts Ping Monitor for MyComputer
            
        .Example
            Invoke-Pingmonitor -network 192.168.1.0
            Description
            -----------
            Starts Ping Monitor for network 192.168.1.0
            
        .Example
            $Servers | Invoke-Pingmonitor 
            Description
            -----------
            Starts Ping Monitor for all Computers in $Servers
                    
        .OUTPUTS
            System.String
            
        .INPUTS
            System.String
            
        .Link
            Get-IPRange
            Ping-Subnet
            Get-NetworkAddress
            ConvertTo-BinaryIP 
            ConvertFrom-BinaryIP 
            ConvertTo-MaskLength 
            ConvertFrom-MaskLength 
        
        .Notes
            NAME:      Invoke-PingMonitor
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [cmdletbinding(DefaultParameterSetName="byName")]
    Param(
        [Alias('dnsHostName')]
        [Parameter(ValueFromPipeline=$true,ParameterSetName="byName")]
        [string]$ComputerName,
        [Parameter(ParameterSetName="byNetwork")]
        [string]$Network,
        [Parameter()]
        [switch]$TitleBar
    )
    Begin 
    {
    
        function Start-IPMonitor
        {
            Param($IPAddresses)
            Write-Verbose " [Start-IPMonitor] :: Called"
            function pServer 
            {
                Param([string]$srv)
                $pingresult = Get-WmiObject win32_pingstatus -f "address='$srv' and Timeout=1000"
                if($pingresult.statuscode -eq 0) {$true} else {$false}
            }
            $rows = [math]::Floor($host.UI.RawUI.BufferSize.Width/16)
            $i = 1
            while($true)
            {
                $oldpos = $host.UI.RawUI.CursorPosition
                foreach($IP in $IPAddresses)
                {
                    if($TitleBar){$host.UI.Rawui.WindowTitle = " == Processing $IP == "}
                    if(($i -lt $rows) -and ($i -lt $IPAddresses.count))
                    {
                        if(pServer $IP){Write-Host $IP.padright(15) -noNewLine -foregroundcolor green }
                        else{Write-Host $IP.padright(15) -noNewLine -foregroundcolor red}
                        $i = $i+1
                    }
                    else 
                    {
                        if(pServer $IP){Write-Host $IP.padright(15) -foregroundcolor green }
                        else{Write-Host $IP.padright(15) -foregroundcolor red}
                        $i = 1
                    }
                }
                start-sleep 5
                $host.UI.RawUI.CursorPosition = $oldpos
            }
        }
        Write-Verbose " [Invoke-PingMonitor] :: Start Begin"
        Write-Verbose " [Invoke-PingMonitor] :: ParameterSet = $($pscmdlet.ParameterSetName)"
        switch ($pscmdlet.ParameterSetName)
        {
            "byName"        {$Servers = @()}
            "byNetwork"        {
                                Write-Verbose " [Invoke-PingMonitor] :: Network = $Network"
                                $Net,$Mask = $network -split "/"
                                $Mask = ConvertFrom-MaskLength -mask $Mask
                                Write-Verbose " [Invoke-PingMonitor] :: Net = $Net"
                                Write-Verbose " [Invoke-PingMonitor] :: Mask = $Mask"
                                Write-Verbose " [Invoke-PingMonitor] :: Calling et-IPRange -IP $Net -netmask $Mask"
                                $IPs = Get-IPRange -IP $Net -netmask $Mask
                                Start-IPMonitor $IPs
                            }
        }
        
        Write-Verbose " [Invoke-PingMonitor] :: End Begin"
    
    }
    Process 
    {
    
        $Servers += $Computername
    
    }
    End 
    {
    
        if($Servers.Count -gt 0)
        {
            Start-IPMonitor $Servers
        }
    
    }
}
    
#endregion 


#region Invoke-uac 

function Invoke-uac
{
    
    <#
        .Synopsis 
            Creates an elevated shell. 
            
        .Description
            Creates an elevated shell.
            
        .Parameter NoProfile
            Avoids loading profile information
            
        .Example
            Invoke-UAC
            Description
            -----------
            Creates a new shell with elevation
    
        .Notes
            NAME:      Invoke-UAC
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    Param([switch]$noProfile)
    $shell = new-Object -com shell.application
    $myPath = $pwd
    $argString = [string]::join(" ",$args)
    if($argString){
    if($noProfile){$command = "-noprofile "}
        $command += "-noexit -command `"& {`prompt ;cd $myPath;`$host.UI.RawUI.CursorPosition = `$PromptCursorPosition;
    Write-Host `"$argString`" ; invoke-expression '$argString'}`" "
    }
    else
    {
    if($noProfile){$command = "-noprofile "}
        $command += "-noexit -command `"& {cd $myPath}"
    }
    $shell.ShellExecute("powershell.exe",$command,$PWD,"runas")
}
    
#endregion 


#region Invoke-WhoAmI 

function Invoke-WhoAmI
{
    
    <#
        .Synopsis 
            Gets the Identity for the local user.
            
        .Description
            Gets the Identity for the local user.
            
        
        .Example
            Invoke-WHOAmI
            Description
            -----------
            Returns PSCustomObject for the local user
    
        .OUTPUTS
            PSCustomObject
            
        .Link
            ConvertTo-Name
            
        .Notes
            NAME:      Invoke-WHOAmI
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    $myobj = @{} # "" | Select User,Groups,RawObject
    $Self = [System.Security.Principal.WindowsIdentity]::GetCurrent()
    $myobj.User = ConvertTo-Name $self.User
    $myobj.Groups = $Self.Groups | %{ConvertTo-Name $_.Value}
    $myobj.RawObject = $self
    
    $obj = New-Object PSObject -Property $myobj
    $obj.PSTypeNames.Clear()
    $obj.PSTypeNames.Add('BSonPosh.WhoAMI')
    $obj

}
    
#endregion 


#region New-TempFile 

function New-TempFile
{
    
    <#
        .Synopsis 
            Creates a temp file to store data.
            
        .Description
            Creates a temp file to store data.
            
        .Parameter Server
            Name of the Server to Process.
            
        .Example
            New-Tempfile
            Description
            -----------
            Creates a Temp in the default temp folder
            
        .Example
            New-Tempfile c:\temp
            Description
            -----------
            Creates Temp file in C:\temp
            
    .OUTPUTS
            System.IO.FileInfo
            
        .INPUTS
            System.String
        
        NAME:      New-TempFile
        AUTHOR:    YetiCentral\bshell
        Website:   www.bsonposh.com
        #Requires -Version 2.0
    #>
    
    [cmdletbinding()]
    param (
        [Parameter()]
        [string]$Path = [environment]::GetEnvironmentVariable("TEMP")
    )
    if(!(Test-Path -Path $path)){New-Item -ItemType Directory -Path $Path}
    
    $FileName = [System.IO.Path]::GetRandomFileName()
    
    $file = Join-Path -Path $Path -ChildPath $FileName
    
    New-Item -ItemType File -Path $file
}
    
#endregion 


#region pig 

function pig 
{
    param($ComputerName)
    $arguments = "/T:0C","/k ping -t $ComputerName -l 2400 -4"
    $Cmd = "cmd.exe"
    Microsoft.PowerShell.Management\Start-Process $cmd -ArgumentList $arguments
}
    
#endregion 


#region Ping-Subnet 

function Ping-Subnet
{
    
    <#
        .Synopsis 
            Ping a subnet returning all alive hosts.
            
        .Description
            Ping a subnet returning all alive hosts.
                        
        .Parameter IP 
            IP of a host on the Network.
            
        .Parameter Network 
            Network Address.
        
        .Example
            Ping-Subnet -IP 192.168.1.0 -Netmask 255.255.255.0
            Description
            -----------
            Pings all host on 192.168.1.0 network using mask 255.255.255.0
            
        .Example
            Ping-Subnet -IP 192.168.1.0 -Netmask /24
            Description
            -----------
            Pings all host on 192.168.1.0 network using CIDR notation
            
        .OUTPUTS
            System.String
            
        .INPUTS
            System.String
            
        .Link
            Get-IPRange
            Invoke-Pingmonitor
            Get-NetworkAddress
            ConvertTo-BinaryIP 
            ConvertFrom-BinaryIP 
            ConvertTo-MaskLength 
            ConvertFrom-MaskLength 
            
        NAME:      Ping-Subnet
        AUTHOR:    Glenn Sizemore
        Website:   http://get-admin.com
        Version:   1
        #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [Parameter(Mandatory=$True)]
        [string]$IP,
        
        [Alias("mask")]
        [Parameter(Mandatory=$True)]
        [string]$netmask
    )
    Begin 
    {
        $IPs = New-Object System.Collections.ArrayList
        $Jobs = New-Object System.Collections.ArrayList
        $max = 50  
    }
    
    Process 
    {
    
        #get every ip in scope
        Get-IPRange $IP $netmask | %{
            [void]$IPs.Add($_)
        }
        #loop untill we've pinged them all
        While ($IPs.count -gt 0 -or $jobs.count -gt 0) 
        {
            #if we have open spots kick off some more
            if ($jobs.count -le $max) 
            {
                # determin how many to kick off
                $addjobs = ($max - $jobs.count)
                foreach ($IP in ($IPS | Select -first $addjobs)) 
                {
                    #save the job id, and move on
                    [VOID]$Jobs.Add((gwmi -q "SELECT Address,StatusCode FROM Win32_Pingstatus WHERE Address = `'$IP`'" -asjob).Id)
                    #remove the IP from our pool
                    $IPs.Remove($IP)
                }
            }
            #we'll use this array to track what's comeback
            $Clean = @()
            
            foreach ($J in $jobs) 
            {
                # If this job is done get the results
                if ((Get-Job -id $j).JobStateInfo.state -eq 'Completed') 
                {
                    # if the ping was sucessfull return the IP Address
                    write-output (Receive-Job -id $j) | ?{$_.StatusCode -eq 0}| select -expand Address
                    # dispose of the job
                    remove-job -id $j
                    $clean += $j
                }
            }
            foreach ($c in $Clean) 
            {
                #remove the jobs that we just processed
                $jobs.remove($c)
            }
        }
    
    }
}
    
#endregion 


#region png 

function png
{
    param($ComputerName)
    $arguments = "/T:0C","/k ping -t $ComputerName -4"
    $Cmd = "cmd.exe"
    Microsoft.PowerShell.Management\Start-Process $cmd -ArgumentList $arguments
}
    
#endregion 


#region Resolve-Host 

function Resolve-Host
{
        
    <#
        .Synopsis 
            Gets the DNS info for specified host.
            
        .Description
            Gets the DNS info for specified host.
            
        .Parameter ComputerName
            Name of the Computer to get the OS Version from (Default is localhost.)
    
        .Example
            Resolve-Host -Target MyServer
            Description
            -----------
            Gets DNS info from MyServer
            
        .Example
            $Servers | Resolve-Host
            Description
            -----------
            Gets DNS info for each machine in the pipeline
            
        .OUTPUTS
            PSCustomObject
            
        .INPUTS
            System.String
            
        .Link
            N/A
            
        .Notes
            NAME:      Resolve-Host
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [cmdletbinding()]
    Param(
        [alias('dnsHostName')]
        [alias('name')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME
    )
    
    Begin 
    {
    
        $IPs = @{n="IP";e={$_.addresslist | %{$_.IPAddressToString}}}
        $IsUp = @{n="IsPingable";e={if($_.addresslist[0].IPAddressToString | Test-Host){$true}else{$false}}}
    }
    
    Process 
    {
        Try
        {
            $IPHostEntry = [system.net.dns]::GetHostEntry($ComputerName)
            $IPHostEntry | select HostName,$IPs,$IsUp
        }
        catch
        {
            Write-Host "Unable to resolve host: $ComputerName"        
        }
    }
}
    
#endregion 


#region Restart-RemoteService

function Restart-RemoteService 
{
        
    <#
        .Synopsis 
            Restarts a Service
            
        .Description
            Restarts a Service and all dependant services (if any)
            
        .Parameter ServiceName
            The name of the service to restart
            
        .Parameter ComputerName
            The Computer you want to restart the service on (default is localhost)
            
        .Parameter WaitTime
            How long to wait before giving up. (Default 5min)
            
        .Example
            Restart-RemoteService -ServiceName dnscache -computername MyServer1
            Description
            -----------
            Restarts dnscache on server MyServer1
            
        .OUTPUTS
            System.ServiceProcess.ServiceController
            
        .Link
            N/A
            
        .Notes
            NAME:      Restart-RemoteService 
            AUTHOR:    YetiCentral\bshell
            Website:   www.bsonposh.com
        #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [Parameter(mandatory=$true)]
        [string]$ServiceName,
        
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME,
        
        [Parameter()]
        [int]$WaitTime = 300
    )
    
    Begin 
    {
    
        function Get-Dependents
        {
            Param([System.ServiceProcess.ServiceController]$MasterService)
            Write-Verbose " [Get-Dependents] ::          + Getting Dependent Services for $($MasterService.Name)"
            foreach($dependent in $MasterService.DependentServices)
            {
                if($dependent)
                {
                    Write-Verbose " [Get-Dependents] ::            - Found Dependent Service [$($dependent.Name)]"
                    $dependent
                    Get-Dependents $dependent
                }
            }
        }
        
        [system.Reflection.Assembly]::LoadWithPartialName("System.ServiceProcess") | out-Null
        $ErrorActionPreference = "SilentlyContinue"
        Write-Verbose " [Restart-RemoteService] :: ServiceName = $ServiceName"
    
    }
    
    Process
    {
    
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        if(Test-Host $ComputerName -TCPPort 135)
        {
            Write-Verbose " [Restart-RemoteService] :: ComputerName = $ComputerName"
            try
            {
                Write-Verbose " [Restart-RemoteService] :: - Getting Service [$ServiceName]"
                $Service = New-Object System.ServiceProcess.ServiceController($ServiceName,$ComputerName)
        
                Write-Verbose " [Restart-RemoteService] :: - Getting Dependent Services"
                $DependentServices = Get-Dependents $Service
                
                try
                {
                    if($Service.State -ne "Stopped")
                    {
                        Write-Verbose " [Restart-RemoteService] :: + Stopping [$ServiceName] and dependent Services"
                        $Service.Stop()
                    }
                }
                catch
                {
                    Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
                    continue
                }
        
                try
                {
                    Write-Verbose " [Restart-RemoteService] ::   - Waiting for Service to Stop (${WaitTime}sec)"
                    $Service.WaitForStatus("Stopped",(new-object System.TimeSpan(0,0,$WaitTime)))
                }
                catch
                {
                    Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
                    continue
                }
                
                try
                {
                    if($Service.State -ne "Running")
                    {
                        Write-Verbose " [Restart-RemoteService] :: + Starting [$ServiceName]"
                        $Service.Start()
                    }
                }
                catch
                {
                    Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
                    continue
                }
        
                try
                {
                    Write-Verbose " [Restart-RemoteService] ::   - Waiting for Service $($Service.Name) to Start (${WaitTime}sec)"
                    $Service.WaitForStatus("Running",(new-object System.TimeSpan(0,0,$WaitTime)))
                }
                catch
                {
                    Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
                    continue
                }
        
                if($DependentServices)
                {
                    Write-Verbose " [Restart-RemoteService] ::   - Starting Dependant Services"
                    foreach($dependent in $DependentServices)
                    {
                        $dependent.Refresh()
                        if($dependent.status -eq "Stopped")    
                        {
                            $dependent.Start()
                            Write-Verbose " [Restart-RemoteService] ::     - Waiting for Service [$($Dependent.Name)] to Start (${WaitTime}sec)"
                            $dependent.WaitForStatus("Running",(new-object System.TimeSpan(0,0,$WaitTime)))
                        }
                    }
                }
                $Service.Refresh()
                $Service
                $Service.DependentServices
            }
            catch
            {
                Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
            }
        }
        else
        {
            Write-Host " Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
        }
    
    }
}
    
#endregion 


#region Select-LargeFile 

function Select-LargeFile
{
        
    <#
        .Synopsis 
            Returns files that match the size specified.
            
        .Description
            Returns files that match the size specified.
            
        .Parameter Size
            The size to check (default 100mb.)
            
        .Parameter Path
            The Path to the file(s) to check
            
        .Parameter Recurse
            Does recursive search.
            
        .Example
            Select-LargeFile -path c:\data
            Description
            -----------
            Selects all the files larger than 100mb in the root of c:\data
            
        .Example
            Select-LargeFile -path c:\data -recurse
            Description
            -----------
            Selects all the files larger than 100mb contained in c:\data recursively
            
        .Example
            dir c:\data | Select-LargeFile -size 1gb
            Description
            -----------
            Selects all the files larger than 1gb in the root of c:\data
            
        .OUTPUTS
            System.IO.FileInfo
            
        .Notes
            NAME:      Select-LargeFile
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [cmdletbinding()]
    Param(
    
        [Parameter()]
        [int]$size = 100mb,
        
        [alias('FullName')]
        [Parameter(ValueFromPipelineByPropertyName =$true)]
        [string]$Path,
    
        [Parameter()]
        [switch]$recurse
    
    )
    Process 
    {
    
        Write-Verbose "Path : $path"
        if($recurse)
        {
            foreach($file in (get-childitem $path -rec | where-object{(!$_.PSisContainer) -and ($_.Length -ge $size)}))
            {
                $FileSize = ("{0:n2}MB" -f ($file.length/1mb))
                $file | add-member -Name FileSize -MemberType noteproperty -Value $FileSize
                $file
            }
        }
        else
        {
            foreach($file in (get-item $path | where-object{(!$_.PSisContainer) -and ($_.Length -ge $size)}))
            {
                $FileSize = ("{0:n2}MB" -f ($file.length/1mb))
                $file | add-member -Name FileSize -MemberType noteproperty -Value $FileSize
                $file
            }
        }
            
    
    }
}
    
#endregion 


#region Set-NetworkLocation 

function Set-NetworkLocation
{
        
    <#
        .Synopsis 
            Sets the network(s) on the host.
            
        .Description
            Sets the network(s) on the host.
            
        .Parameter Category
            The Category to set the network(s) to. Valid Value: Public, Private, or Domain.
            
        .Parameter Name
            Name of the Network (default to all.) Uses RegEX.
            
        .Example
            Set-NetworkLocation -category Private
            Description
            -----------
            Sets Network Location to Private for all networks.
        
        .Example
            Set-NetworkLocation -category Private -Name MyNetwork
            Description
            -----------
            Sets Network Location to Private for MyNetwork.
            
        .OUTPUTS
            PSCustomObject
            
        .Link
            Get-NetworkLocation
            
        .Notes
            NAME:      Set-NetworkLocation
            AUTHOR:    YetiCentral\bshell
            Website:   www.bsonposh.com
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding(SupportsShouldProcess=$true)]
    Param(
        [Parameter(Mandatory=$true)]
        [ValidateSet("Public", "Private", "Domain")]
        [String]$CATEGORY,
        
        [Parameter()]
        [string]$Name = ".*",
        
        [Parameter()]
        [switch]$Force
    )
    if([environment]::OSVersion.version.Major -lt 6) 
    {
        Write-Host "Network Location is only valid with Vista and above. Exiting" -ForegroundColor Yellow
        return 
    }
    
    # Skip network location setting if local machine is joined to a domain. 
    if(1,3,4,5 -contains (Get-WmiObject win32_computersystem).DomainRole) 
    {
        if(!$Force)
        {
            $yes = new-Object System.Management.Automation.Host.ChoiceDescription "&Yes",""
            $no  = new-Object System.Management.Automation.Host.ChoiceDescription "&No",""
            $choices = [System.Management.Automation.Host.ChoiceDescription[]]($yes,$no)
            $caption = "Host is in a domain."
            $message = "Are you sure you want to continue?"
            $result = $host.ui.PromptForChoice($caption,$message,$choices,0)
            if($Result -eq 1){return}
        }
    } 
    
    try 
    {
        # Get network connections 
        $networkListManager = [Activator]::CreateInstance([Type]::GetTypeFromCLSID([Guid]"{DCB00C01-570F-4A9B-8D69-199FDBA5723B}")) 
        $connections = $networkListManager.GetNetworkConnections() | ?{$_.GetNetwork().GetName() -match $Name}
        
        # Set network location to Private for all networks 
        foreach($conn in $connections)
        {
            $ConnName = $conn.GetNetwork().GetName()
            if($PSCmdlet.ShouldProcess($CATEGORY,"Setting Network Location on $ConnName"))
            {
                switch ($CATEGORY)
                {
                    "Public"    {$conn.GetNetwork().SetCategory(0)}
                    "Private"    {$conn.GetNetwork().SetCategory(1)}
                    "Domain"    {$conn.GetNetwork().SetCategory(2)}
                }
            }
        }
        Get-NetworkLocation -Name $Name
    }
    catch
    {
        Write-Host "ERROR: $($Error[0])" -ForegroundColor Red
    }
}
    
#endregion 


#region Set-ServiceAccount

function Set-ServiceAccount
{

	<#
        .Synopsis 
            Sets UserName and Password on Service.
            
        .Description
            Sets UserName and Password on Service.
            
        .Parameter ServiceName
            The name of the service to set the UserName and Password on.
            
        .Parameter ComputerName
            The Computer you want to set the service password on (default is localhost.)
            
        .Parameter UserName
            Account name the service runs under. Depending on the service type, the account name may be in the form of DomainName\Username or .\Username. The service process will be logged using one of these two forms when it runs. If the account belongs to the built-in domain, .\Username can be specified. If NULL is specified, the service will be logged on as the LocalSystem account. For kernel or system-level drivers, StartName contains the driver object name (that is, \FileSystem\Rdr or \Driver\Xns) that the input and output (I/O) system uses to load the device driver. If NULL is specified, the driver runs with a default object name created by the I/O system based on the service name, for example, "DWDOM\Admin".

            You also can use the User Principal Name (UPN) format to specify the UserName, for example, Username@DomainName.
            
        .Parameter Password
            Password to the account name specified by the UserName parameter. If no password set an empty string will be used.
            
        .Example
            Set-ServiceAccount -ServiceName fax -UserName "user@domain.com" -Password p@ssw0rd1
            Description
            -----------
            Sets the UserName and Password on the Fax Service.
            
        .Example
            Get-Service Fax -ComputerName RemoteMachine | Set-ServiceAccount -UserName "user@domain.com" -Password p@ssw0rd1
            Description
            -----------
            Sets the UserName and Password for the Fax service on RemoteMachine.
            
        .OUTPUTS
            System.String
            
        .Link
            N/A
            
        .Notes
            NAME:      Set-ServiceAccount 
            AUTHOR:    YetiCentral\bshell
            Website:   www.bsonposh.com
            #Requires -Version 2.0
    #>
	
	[CmdletBinding(SupportsShouldProcess=$true)]
	Param(
	
		[Parameter(ValueFromPipelineByPropertyName=$true,Mandatory=$true)]
		[alias('Name')]
		[String]$ServiceName,
		
		[alias('dnsHostName','MachineName')]
        [Parameter(ValueFromPipelineByPropertyName=$true)]
        [String]$ComputerName = $Env:COMPUTERNAME,
		
		[Parameter()]
		[String]$UserName,
		
		[Parameter()]
		[String]$Password = [string]::Empty
	)
	Begin
	{
		function ConvertFrom-ResultCode([int]$code)
		{
			switch -exact ($code)
			{
				0 {"Success"}
				1 {"Not Supported"}
				2 {"Access Denied"}
				3 {"Dependent Services Running"}
				4 {"Invalid Service Control"}
				5 {"Service Cannot Accept Control"}
				6 {"Service Not Active"}
				7 {"Service Request Timeout"}
				8 {"Unknown Failure"}
				9 {"Path Not Found"}
				10 {"Service Already Running"}
				11 {"Service Database Locked"}
				12 {"Service Dependency Deleted"}
				13 {"Service Dependency Failure"}
				14 {"Service Disabled"}
				15 {"Service Logon Failure"}
				16 {"Service Marked For Deletion"}
				17 {"Service No Thread"}
				18 {"Status Circular Dependency"}
				19 {"Status Duplicate Name"}
				20 {"Status Invalid Name"}
				21 {"Status Invalid Parameter"}
				22 {"Status Invalid Service Account"}
				23 {"Status Service Exists"}
				24 {"Service Already Paused"}
 			}
		}
	}
	Process
	{
		# Setup for WMI
		$class = "Win32_Service"
		$Method = "Change"
		$Filter = "Name=`'$ServiceName`'"
		
		# Getting Service Via WMI
		$MyService = Get-WMIObject $Class -computer $ComputerName -filter $Filter
		
		# Setting Parameters for Change Method
		$inparams = $MyService.psbase.GetMethodParameters($Method)
		$inparams["StartName"] = $UserName
		$inparams["StartPassword"] = $Password
		
		# Calling Change Method and Return $results
		if($PSCmdlet.ShouldProcess($ServiceName,"Setting Service Password on $ComputerName"))
		{
			$result = $MyService.psbase.InvokeMethod($Method,$inparams,$null)
			if($result.ReturnValue -eq 0)
			{
				ConvertFrom-ResultCode $Result.ReturnValue
			}
			else
			{
				ConvertFrom-ResultCode $Result.ReturnValue
			}
		}
	}
}

#endregion


#region Start-RemoteService 

function Start-RemoteService 
{
        
    <#
        .Synopsis 
            Starts a Remote Service
            
        .Description
            Starts a Service and all dependant services (if any)
            
        .Parameter ServiceName
            The name of the service to start
            
        .Parameter ComputerName
            The Computer you want to start the service on (default is localhost)
            
        .Example
            Start-RemoteService -ServiceName dnscache -computername MyServer1
            Description
            -----------
            Starts dnscache on MyServer1
            
        .OUTPUTS
            System.ServiceProcess.ServiceController
            
        .Link
            N/A
            
        .Notes
            NAME:      Start-RemoteService 
            AUTHOR:    YetiCentral\bshell
            Website:   www.bsonposh.com
            #Requires -Version 2.0
    #>
    
    [cmdletbinding()]
    Param(
        [Parameter(mandatory=$true)]
        [string]$ServiceName,
        
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME
    )
    
    Process 
    {
    
        Write-Verbose " [Start-RemoteService] :: Starting Service [$ServiceName] on Computer [$ComputerName]"
        $ScriptBlock = { Param($name) Start-Service $name }
        Invoke-Command -ComputerName $ComputerName -ScriptBlock $ScriptBlock -ArgumentList $ServiceName
    
    }
}
    
#endregion 


#region Stop-IE 

function Stop-IE
{
    
    [Cmdletbinding(SupportsShouldProcess=$true)]
    Param()
    ps iexplore -ea 0 | kill 

}
    
#endregion 


#region Stop-RemoteProcess

function Stop-RemoteProcess
{
        
    <#
        .Synopsis 
            Stops a Process on a remote host.
            
        .Description
            Stops a Process on a remote host.
            
        .Parameter ComputerName
            Name of the Computer to stop the process on (Default is localhost.)
            
        .Parameter ID
            ID of the Process to stop.
            
        .Parameter Name
            Name of the Process to stop.
            
        .Example
            Stop-RemoteProcess -id 342
            Description
            -----------
            Stops process with id 342 on localhost
            
        .Example
            Get-Process notepad -computername MyServer | Stop-RemoteProcess
            Description
            -----------
            Stops all processes named notepad.exe on MyServer
    
        .Example
            Stop-RemoteProcess -ComputerName MyServer -id 342
            Description
            -----------
            Stops process with id 342 on MyServer
            
        .Example
            $Servers | Stop-RemoteProcess -name notepad.exe
            Description
            -----------
            Stops all processes named 'notepad.exe' on all the servers in $Servers
            
        .OUTPUTS
            System.String
            
        .Notes
            NAME:      Stop-RemoteProcess 
            AUTHOR:    YetiCentral\bshell
            Website:   www.bsonposh.com
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding(DefaultParameterSetName="Name",SupportsShouldProcess=$true)]
    Param(
    
        [alias('MachineName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME,
        
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true,ParameterSetName="ID")]
        [int]$Id,
        
        [Parameter(ParameterSetName="Name")]
        [string]$Name
        
    )
    
    Begin
    {
        Function ConvertTo-RealName ($Code)
        {
            switch -exact ($Code)
            {
                0   {"Successful Completion"}
                2   {"Access Denied"}
                3   {"Insufficient Privilege"}
                8   {"Unknown Failure"}
                9   {"Path Not Found"}
                21  {"Invalid Parameter"}
            }
        }
    }
    
    Process 
    {
        Write-Verbose " [Stop-RemoteProcess] :: Process Start"
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        if(Test-Host $ComputerName -TCPPort 135)
        {
            try
            {
                switch ($pscmdlet.ParameterSetName)
                {
                    "ID"    {
                                $Query = "Select * from Win32_Process WHERE ProcessID='$ID'"
                                $Type = "for ID [$ID] on $ComputerName"
                            }
                    "Name"  {
                                $Query = "Select * from Win32_Process WHERE Name='$Name'"
                                $Type = "for Name [$Name] on $ComputerName"
                            }
                }
                if($PSCmdlet.ShouldProcess($ComputerName,"Killing Processes matching $Query"))
                {
                    $results = Get-WmiObject -query $Query -ComputerName $ComputerName | %{$_.Terminate()}
                    foreach($result in $results)
                    {
                        $Message = ConvertTo-RealName $result.ReturnValue
                        Write-Host "Stop-RemoteProcess returned [$Message]" $Type
                    }
                }
            }
            catch
            {
                Write-Verbose " [Stop-RemoteProcess] :: [$ComputerName] Failed with Error: $($Error[0])" 
            }
        }
        Write-Verbose " [Stop-RemoteProcess] :: Process End"
    }
    
}
#endregion 


#region Stop-RemoteService

function Stop-RemoteService
{
        
    <#
        .Synopsis 
            Stops a Remote Service
            
        .Description
            Stops a Service and all dependant services (if any)
            
        .Parameter ServiceName
            The name of the service to stop
            
        .Parameter ComputerName
            The Computer you want to stop the service on (default is localhost)
            
        .Example
            Stop-RemoteService -ServiceName dnscache -computername MyServer1
            Description
            -----------
            Stops dnscache on MyServer1
            
            
        .OUTPUTS
            System.ServiceProcess.ServiceController
            
        .Link
            N/A
            
        .Notes
            NAME:      Stop-RemoteService 
            AUTHOR:    YetiCentral\bshell
            Website:   www.bsonposh.com
            LASTEDIT:  04/20/2010 18:25:15
        #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [Parameter(mandatory=$true)]
        [string]$ServiceName,
        
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME,
        
        [Parameter()]
        [switch]$Force
    )
    Process 
    {
    
        Write-Verbose " [Stop-RemoteService] :: Stopping Service [$ServiceName] on Computer [$ComputerName]"
        $ScriptBlock =  { Param($name,$Force) Stop-Service $name -Force:$Force }
        Invoke-Command -ComputerName $ComputerName -ScriptBlock $ScriptBlock -ArgumentList $ServiceName,$Force
    
    }
}
    
#endregion 


#region Test-Host 

function Test-Host
{
        
    <#
        .Synopsis 
            Test a host for connectivity using either WMI ping or TCP port
            
        .Description
            Allows you to test a host for connectivity before further processing
            
        .Parameter Server
            Name of the Server to Process.
            
        .Parameter TCPPort
            TCP Port to connect to. (default 135)
            
        .Parameter Timeout
            Timeout for the TCP connection (default 1 sec)
            
        .Parameter Property
            Name of the Property that contains the value to test.
            
        .Example
            cat ServerFile.txt | Test-Host | Invoke-DoSomething
            Description
            -----------
            To test a list of hosts.
            
        .Example
            cat ServerFile.txt | Test-Host -tcp 80 | Invoke-DoSomething
            Description
            -----------
            To test a list of hosts against port 80.
            
        .Example
            Get-ADComputer | Test-Host -property dnsHostname | Invoke-DoSomething
            Description
            -----------
            To test the output of Get-ADComputer using the dnshostname property
            
            
        .OUTPUTS
            System.Object
            
        .INPUTS
            System.String
            
        .Link
            Test-Port
            
        NAME:      Test-Host
        AUTHOR:    YetiCentral\bshell
        Website:   www.bsonposh.com
        LASTEDIT:  02/04/2009 18:25:15
        #Requires -Version 2.0
    #>
    
    [CmdletBinding()]
    
    Param(
    
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true,Mandatory=$True)]
        [string]$ComputerName,
        
        [Parameter()]
        [int]$TCPPort,
        
        [Parameter()]
        [int]$timeout=3000,
        
        [Parameter()]
        [string]$property
        
    )
    Begin 
    {
    
        function PingServer 
        {
            Param($MyHost)
            $ErrorActionPreference = "SilentlyContinue"
            Write-Verbose " [PingServer] :: Pinging [$MyHost]"
            try
            {
                $pingresult = Get-WmiObject win32_pingstatus -f "address='$MyHost'"
                $ResultCode = $pingresult.statuscode
                Write-Verbose " [PingServer] :: Ping returned $ResultCode"
                if($ResultCode -eq 0) {$true} else {$false}
            }
            catch
            {
                Write-Verbose " [PingServer] :: Ping Failed with Error: ${error[0]}"
                $false
            }
        }
    
    }
    
    Process 
    {
    
        Write-Verbose " [Test-Host] :: Begin Process"
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        Write-Verbose " [Test-Host] :: ComputerName   : $ComputerName"
        if($TCPPort)
        {
            Write-Verbose " [Test-Host] :: Timeout  : $timeout"
            Write-Verbose " [Test-Host] :: Port     : $TCPPort"
            if($property)
            {
                Write-Verbose " [Test-Host] :: Property : $Property"
                $Result = Test-Port $_.$property -tcp $TCPPort -timeout $timeout
                if($Result)
                {
                    if($_){ $_ }else{ $ComputerName }
                }
            }
            else
            {
                Write-Verbose " [Test-Host] :: Running - 'Test-Port $ComputerName -tcp $TCPPort -timeout $timeout'"
                $Result = Test-Port $ComputerName -tcp $TCPPort -timeout $timeout
                if($Result)
                {
                    if($_){ $_ }else{ $ComputerName }
                } 
            }
        }
        else
        {
            if($property)
            {
                Write-Verbose " [Test-Host] :: Property : $Property"
                try
                {
                    if(PingServer $_.$property)
                    {
                        if($_){ $_ }else{ $ComputerName }
                    } 
                }
                catch
                {
                    Write-Verbose " [Test-Host] :: $($_.$property) Failed Ping"
                }
            }
            else
            {
                Write-Verbose " [Test-Host] :: Simple Ping"
                try
                {
                    if(PingServer $ComputerName){$ComputerName}
                }
                catch
                {
                    Write-Verbose " [Test-Host] :: $ComputerName Failed Ping"
                }
            }
        }
        Write-Verbose " [Test-Host] :: End Process"
    
    }
    
}
    
#endregion 


#region Test-Is64Bit 

function Test-Is64Bit 
{
        
    <#
        .Synopsis 
            Tests the OS for x64 support on the specified host.
            
        .Description
            Tests the OS for x64 support on the specified host.
            
        .Parameter ComputerName
            Name of the Computer to get the OS Version from (Default is localhost.)
            
        .Parameter PassThru
            If test is passed the object is passed on.
            
        .Example
            Test-Is64Bit
            Description
            -----------
            Returns $True if the local host is 64bit
    
        .Example
            Test-Is64Bit -ComputerName MyServer
            Description
            -----------
            Returns $True if MyServer is 64bit
            
        .Example
            $Servers | Test-Is64Bit -passthru
            Description
            -----------
            Passes on Objects that pass the 64 bit test.
            
        .OUTPUTS
            Boolean
            
        .INPUTS
            System.String
            
        .Link
            N/A
            
        .Notes
            NAME:      Test-Is64Bit
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME,
        
        [Parameter()]
        [switch]$passthru
    )
    Process 
    {
    
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        $Query = "Select AddressWidth from Win32_Processor WHERE AddressWidth=64"
        if(Test-Connection $ComputerName -ea 0)
        {
            $result = Get-WmiObject -Query $Query -ComputerName $ComputerName
            if($result)
            {
                if($passthru){$_}else{$true}
            }
            else
            {
                $false
            }
        }
        else
        {
            Write-Host "Unable to ping [$ComputerName]" -ForegroundColor Red -BackgroundColor Black
        }
    
    }
}
    
#endregion 


#region Test-Port 

function Test-Port
{
        
    <#
        .Synopsis 
            Test a host to see if the specified port is open.
            
        .Description
            Test a host to see if the specified port is open.
                        
        .Parameter TCPPort 
            Port to test (Default 135.)
            
        .Parameter Timeout 
            How long to wait (in milliseconds) for the TCP connection (Default 3000.)
            
        .Parameter ComputerName 
            Computer to test the port against (Default in localhost.)
            
        .Example
            Test-Port -tcp 3389
            Description
            -----------
            Returns $True if the localhost is listening on 3389
            
        .Example
            Test-Port -tcp 3389 -ComputerName MyServer1
            Description
            -----------
            Returns $True if MyServer1 is listening on 3389
                    
        .OUTPUTS
            System.Boolean
            
        .INPUTS
            System.String
            
        .Link
            Test-Host
            Wait-Port
            
        .Notes
            NAME:      Test-Port
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [Parameter()]
        [int]$TCPport = 135,
        [Parameter()]
        [int]$TimeOut = 3000,
        [Alias("dnsHostName")]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [String]$ComputerName = $env:COMPUTERNAME
    )
    Begin 
    {
    
        Write-Verbose " [Test-Port] :: Start Script"
        Write-Verbose " [Test-Port] :: Setting Error state = 0"
    
    }
    
    Process 
    {
    
        Write-Verbose " [Test-Port] :: Creating [system.Net.Sockets.TcpClient] instance"
        $tcpclient = New-Object system.Net.Sockets.TcpClient
        
        Write-Verbose " [Test-Port] :: Calling BeginConnect($ComputerName,$TCPport,$null,$null)"
        try
        {
            $iar = $tcpclient.BeginConnect($ComputerName,$TCPport,$null,$null)
            Write-Verbose " [Test-Port] :: Waiting for timeout [$timeout]"
            $wait = $iar.AsyncWaitHandle.WaitOne($TimeOut,$false)
        }
        catch [System.Net.Sockets.SocketException]
        {
            Write-Verbose " [Test-Port] :: Exception: $($_.exception.message)"
            Write-Verbose " [Test-Port] :: End"
            return $false
        }
        catch
        {
            Write-Verbose " [Test-Port] :: General Exception"
            Write-Verbose " [Test-Port] :: End"
            return $false
        }
    
        if(!$wait)
        {
            $tcpclient.Close()
            Write-Verbose " [Test-Port] :: Connection Timeout"
            Write-Verbose " [Test-Port] :: End"
            return $false
        }
        else
        {
            Write-Verbose " [Test-Port] :: Closing TCP Socket"
            try
            {
                $tcpclient.EndConnect($iar) | out-Null
                $tcpclient.Close()
            }
            catch
            {
                Write-Verbose " [Test-Port] :: Unable to Close TCP Socket"
            }
            $true
        }
    
    }
    
    End 
    {
    
        Write-Verbose " [Test-Port] :: End Script"
    
    }
}
    
#endregion 


#region Test-Service 

function Test-Service
{
        
    <#
        .Synopsis 
            Test a Service.
    
        .Description
            Test a Service.
    
        .Parameter ServiceName
            The name of the service to test
    
        .Parameter ComputerName
            The Computer you want to test the service on (default is localhost)
    
        .Example
            Test-Service -ServiceName dnscache -computername MyServer1
            Description
            -----------
            Test service to see if it is started
    
        .OUTPUTS
            [bool]
    
        .Link
            N/A
    
        .Notes
            NAME:      Test-Service
            AUTHOR:    YetiCentral\bshell
            Website:   www.bsonposh.com
            LASTEDIT:  03/16/2009 18:25:15
        #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [Parameter(mandatory=$true)]
        [string]$ServiceName,
    
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME
    )
    
    Begin 
    {
        Write-Verbose " [Test-Service] :: ServiceName = $ServiceName"
    }
    
    Process 
    {
    
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        if(Test-Host $ComputerName -TCPPort 135)
        {
            Write-Verbose " [Test-Service] :: ComputerName = $ComputerName"
            try
            {
                $Service = Get-Service -Name $ServiceName -ComputerName $ComputerName 
                Write-Verbose " [Test-Service] :: $Service in State [$($Service.Status)]"
                if($Service -and ($Service.Status -eq "Running"))
                {
                    $True
                }
                else
                {
                    $False
                }
            }
            catch
            {
                Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
            }
        }
        else
        {
            Write-Host " Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
        }
    
    }
}
    
#endregion 


#region TS 

function TS 
{
        
    [CmdletBinding()]
    Param(
    
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true,Mandatory=$true)]
        [string]$ComputerName,
        
        [Parameter()]
        [int]$Timeout = 30,
        
        [parameter()]
        [switch]$admin,
        
        [parameter()]
        [switch]$wait
        
    )
    if($wait)
    {
        Wait-Port -ComputerName $ComputerName -TCPPort 3389 -Timeout $Timeout
    }
    
    if(Test-Host -ComputerName $ComputerName -TCPport 3389 -Timeout ($Timeout*1000))
    {
        if($Admin)
        {
            start mstsc -arg /v:$ComputerName,/admin
        }
        else
        {
            start mstsc /v:$ComputerName
        }
    }
    else
    {
        Write-Host "Unable to Connect"
    }
}
    
#endregion 


#region Update-GPO 

function Update-GPO
{
        
    <#
        .Synopsis 
            Refreshes Group Policies settings.
            
        .Description
            Refreshes Group Policies settings.
            
        .Parameter ComputerName
            The Category to set the network(s) to. Valid Value: Public, Private, or Domain.
        
        .Parameter Target
            Specifies that only User or only Computer policy settings are refreshed. 
            By default,both User and Computer policy settings are refreshed.
    
        .Parameter Wait
            Sets the number of seconds to wait for policy processing to finish. 
            The default is 600 seconds. The value '0' means not to wait. The value '-1' means to wait indefinitely. 
            prompt returns, but policy processing continues.
            
        .Parameter Force
            Reapplies all policy settings. By default, only policy settings that have changed are applied.
    
        .Parameter Logoff
            Causes a logoff after the Group Policy settings have been refreshed. 
            This is required for those Group Policy client-side extensions that 
            do not process policy on a background refresh cycle but do process policy when a user logs on. 
            Examples include user-targeted Software Installation and Folder Redirection.
            This option has no effect if there are no extensions called that require a logoff.
            
        .Parameter Boot
            Causes a reboot after the Group Policy settings are refreshed. This is required for those
            Group Policy client-side extensions that do not process policy on a background refresh cycle
            but do process policy at computer startup. Examples include computer-targeted Software Installation. 
            This option has no effect if there are no extensions called that require a reboot.
    
        .Parameter Sync
            Causes the next foreground policy application to be done synchronously. 
            Foreground policy applications occur at computer boot and user logon.
            You can specify this for the user, computer or both using the -Target parameter.
            The -Force and -Wait parameters will be ignored if specified.
            
        .Example
            Update-GPO
            Description
            -----------
            Updates the local group policies.
        
        .Example
            Update-GPO -ComputerName MyServer1
            Description
            -----------
            Updates the group policies on MyServer1.
            
        .OUTPUTS
            PSCustomObject
            
        .Notes
            NAME:      Update-GPO
            AUTHOR:    YetiCentral\bshell
            Website:   www.bsonposh.com
            LASTEDIT:  11/09/2009 
            #Requires -Version 2.0
    #>
    
    [cmdletbinding()]
    Param(
    
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $env:COMPUTERNAME,
        
        [Parameter()]
        [ValidateSet("User", "Computer")]
        [string]$Target,
        
        [Parameter()]
        [int]$Wait,
        
        [Parameter()]
        [switch]$Force,
        
        [Parameter()]
        [switch]$Logoff,
        
        [Parameter()]
        [switch]$Boot,
        
        [Parameter()]
        [switch]$Sync
        
    )
    
    Begin 
    {
    
        Write-Verbose " [Update-GPO] :: Begin Start"
        function Get-ReturnCode($ReturnValue)
        {
            switch ($ReturnValue)
            {
                0 {"Successful Completion"}
                2 {"Access Denied"}
                3 {"Insufficient Privilege"}
                8 {"Unknown failure"}
                9 {"Path Not Found"}
                21 {"Invalid Parameter"}
                default {"Unknown"}
            }
        }
        $InvokeArguments = "gpupdate"
        if($Target)
        {
            $InvokeArguments += " /Target:$Target"
        }
        if($Wait)
        {
            $InvokeArguments += " /Wait:$Wait"
        }
        if($Force)
        {
            $InvokeArguments += " /Force"
        }
        if($Logoff)
        {
            $InvokeArguments += " /Logoff"
        }
        if($Boot)
        {
            $InvokeArguments += " /Boot"
        }
        if($Sync)
        {
            $InvokeArguments += " /Sync"
        }
        Write-Verbose " [Update-GPO] :: Command - $InvokeArguments"
        Write-Verbose " [Update-GPO] :: Begin End"
    
    }
    
    Process 
    {
    
        Write-Verbose " [Update-GPO] :: Process Start"
        $myobj = @{}
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        $myobj.ComputerName = $ComputerName
        if(Test-Host $ComputerName -TCPPort 135)
        {
            Write-Verbose " [Update-GPO] :: Calling Win32_Process::Create on $ComputerName"
            Write-Verbose " [Update-GPO] :: Command - $InvokeArguments"
            try 
            {
                $ReturnValue = Invoke-WmiMethod -Class Win32_Process -ComputerName $ComputerName -Name Create -ArgumentList $InvokeArguments
                Write-Verbose " [Update-GPO] :: Command Returned - $($ReturnValue.ReturnValue)"
                
                $ReturnValueToString = Get-ReturnCode $ReturnValue.ReturnValue
                Write-Verbose " [Update-GPO] :: Command Return String - $ReturnValueToString"
                $myobj.Result = $ReturnValueToString
                
                if($ReturnValue.ReturnValue -eq 0)
                {
                    $myobj.Success = $true
                }
                else
                {
                    $myobj.Success = $false
                }
            }
            catch
            {
                $myobj.Result = $Error[0]
                $myobj.Success = $false
            }
    
        }
        else
        {
            $myobj.Success = $false
            $myobj.Result = "Unable to Connect"
            Write-Host " Unable to Ping or Port 135 not open :: $ComputerName" -ForegroundColor Red
        }
        
        New-Object PSCustomObject -Property $myobj
        
        Write-Verbose " [Update-GPO] :: Process End"
    
    }
}
    
#endregion 


#region Wait-Port 

function Wait-Port
{
        
    <#
        .Synopsis
            Waits for a Port to Open.
            
        .Description
            Waits for a Port to Open.
                        
        .Parameter TCPPort 
            Port to wait for (Default 135.)
            
        .Parameter Timeout 
            How long to wait (in seconds) for the TCP connection (Default 30.)
            
        .Parameter ComputerName 
            Computer to check the port against (Default in localhost.)
            
        .Example
            Wait-Port -tcp 3389
            Description
            -----------
            Waits localhost is listening on 3389
            
        .Example
            Wait-Port -tcp 3389 -ComputerName MyServer1
            Description
            -----------
            Waits until MyServer1 is listening on 3389
                    
        .OUTPUTS
            $Null
            
        .INPUTS
            System.String
            
        .Link
            Test-Host
            Test-Port
        
        .Notes
            NAME:      Wait-Port
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    [cmdletbinding()]
    Param(
    
        [Parameter()]
        [int]$TCPPort,
        
        [Parameter()]
        [int]$Timeout=30,
        
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME
    )
    
    Begin 
    {
    
        Write-Verbose " [Wait-Port] :: Start Begin"
        Write-Verbose " [Wait-Port] :: Port   : $Port"
        Write-Verbose " [Wait-Port] :: Timeout: $Timeout"
        Write-Verbose " [Wait-Port] :: End Begin"
    
    }
    
    Process 
    {
    
        Write-Verbose " [Wait-Port] :: Start Process" 
        for($i = 0 ; $i -lt $Timeout ; $i++)
        {
            $return = Test-Port -ComputerName $ComputerName -TCPport $TCPPort -TimeOut 1000
            if($return)
            {
                return
            }
            else
            {
                Start-Sleep    1
            }
        }
        Write-Verbose " [Wait-Port] :: TIMEOUT"
        Write-Verbose " [Wait-Port] :: End Process"
    
    }
}
    
#endregion 


#region Set-DNSServer

function Set-DNSServer
{
        
    <#
        .Synopsis 
            Sets the DNS Server property on a Network Connection for specified host.
            
        .Description
            Sets the DNS Server property on a Network Connection for specified host.
            
            Warning: This replaces the exisiting setting
            
        .Parameter ComputerName
            Name of the computer to set the DNS server property on.
            
        .Parameter Name
            Name of the NIC to set the DNS server property on. If not specified it selects the first NIC that is IPEnabled and has a Default Gateway.
            
        .Example
            Set-DNSServer -DNS "1.1.1.1","2.2.2.2"
            Description
            -----------
            Sets DNS Server property on a first network connection w/ IPEnabled and Default Gateway on local machine. 
            
        .Example
            Set-DNSServer -ComputerName MyServer -DNS "1.1.1.1","2.2.2.2"
            Description
            -----------
            Sets DNS Server property on a first network connection w/ IPEnabled and Default Gateway on MyServer. 
            
        .Example
            Set-DNSServer -ComputerName MyServer -DNS "1.1.1.1","2.2.2.2" -Name "Intel(R) 82578DM Gigabit Network Connection"
            Description
            -----------
            Sets DNS Server property on "Intel(R) 82578DM Gigabit Network Connection" on MyServer
            
    
        .OUTPUTS
            String
            
        .INPUTS
            System.String
            
        .Link
            N/A
            
        .Notes
            NAME:      Set-DNSSetting
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding(SupportsShouldProcess=$true)]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME,
        
        [Parameter(Mandatory=$True)]
        [String[]]$DNSServers,
        
        [Parameter(ValueFromPipelineByPropertyName=$true)]
        [String]$Name
    )
    Begin
    {
        function ConvertFrom-SetDNSServerSearchOrderResult($Result)
        {
            Switch -exact ($Result)
            {
                0	{"Successful completion. No reboot is required."}
                1	{"Successful completion. Reboot is required."}
                64	{"Method not supported on this platform."}
                65	{"Unknown failure."}
                66	{"Invalid subnet mask."}
                67	{"An error occurred while processing an instance that is returned."}
                68	{"Invalid input parameter."}
                69	{"More than five gateways specified."}
                70	{"Invalid IP address."}
                71	{"Invalid gateway IP address."}
                72	{"An error occurred while accessing the registry for the requested information."}
                73	{"Invalid domain name."}
                74	{"Invalid host name."}
                75	{"No primary or secondary WINS server defined."}
                76	{"Invalid file."}
                77	{"Invalid system path."}
                78	{"File copy failed."}
                79	{"Invalid security parameter."}
                80	{"Unable to configure TCP/IP service."}
                81	{"Unable to configure DHCP service."}
                82	{"Unable to renew DHCP lease."}
                83	{"Unable to release DHCP lease."}
                84	{"IP not enabled on adapter."}
                85	{"IPX not enabled on adapter."}
                86	{"Frame or network number bounds error."}
                87	{"Invalid frame type."}
                88	{"Invalid network number."}
                89	{"Duplicate network number."}
                90	{"Parameter out of bounds."}
                91	{"Access denied."}
                92	{"Out of memory."}
                93	{"Already exists."}
                94	{"Path, file, or object not found."}
                95	{"Unable to notify service."}
                96	{"Unable to notify DNS service."}
                97	{"Interface not configurable."}
                98	{"Not all DHCP leases can be released or renewed."}
                100	{"DHCP not enabled on adapter."}
            }
        }
        
        Write-Verbose " [Set-DNSServer] :: Start Begin"
        Write-Verbose " [Set-DNSServer] :: DNSServers   - $DNSServers"
    }
    Process 
    {
        Write-Verbose " [Set-DNSServer] :: Start Process"
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
            
        }
        Write-Verbose " [Set-DNSServer] :: `$ComputerName - $ComputerName"
        Write-Verbose " [Set-DNSServer] :: Testing Connectivity"
        if(Test-Host $ComputerName -TCPPort 135)
        {
            Write-Verbose " [Set-DNSServer] :: Connectivity Passed"
            try
            {
                if($Name)
                {
                    $Query = "SELECT * FROM Win32_NetworkAdapterConfiguration WHERE Description='$Name'"
                    Write-Verbose " [Set-DNSServer] :: Getting NICs using - Get-WmiObject -Query $Query -ComputerName $ComputerName -ea STOP"
                    $NIC = Get-WmiObject -Query $Query -ComputerName $ComputerName -ea STOP 
                }
                else
                {
                    $Query = "SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled=TRUE"
                    Write-Verbose " [Set-DNSServer] :: Getting NICs using - Get-WmiObject -Query $Query -ComputerName $ComputerName -ea STOP"
                    $NIC = Get-WmiObject -Query $Query -ComputerName $ComputerName -ea STOP | ?{$_.DefaultIPGateway} | Select -First 1
                }
                
                if($PSCmdlet.ShouldProcess($NIC.Description,"Setting DNS Servers [$DNSServers]"))
                {
                    $Result = $NIC.SetDNSServerSearchOrder($DNSServers)
                    Write-Verbose " [Set-DNSServer] :: Converting Return code [$($Result.ReturnValue)] to String"
                    ConvertFrom-SetDNSServerSearchOrderResult $Result.ReturnValue
                }
 
            }
            catch
            {
                Write-Host " [Set-DNSServer] ::  Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
            }
        }
        else
        {
            Write-Host " Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
        }
        Write-Verbose " [Set-DNSServer] :: End Process"
    }
}
    
#endregion # Set-DNSServer


#region Add-DNSServer

function Add-DNSServer
{
        
    <#
        .Synopsis 
            Adds the DNS Server property on a Network Connection for specified host.
            
        .Description
            Adds the DNS Server property on a Network Connection for specified host.
            
        .Parameter ComputerName
            Name of the computer to set the DNS server property on.
            
        .Parameter Name
            Name of the NIC to set the DNS server property on. If not specified it selects the first NIC that is IPEnabled and has a Default Gateway.
            
        .Example
            Add-DNSServer -DNS "3.3.3.3"
            Description
            -----------
            Adds DNS Server property on a first network connection w/ IPEnabled and Default Gateway on local machine. 
            
        .Example
            Add-DNSServer -ComputerName MyServer -DNS "3.3.3.3"
            Description
            -----------
            Adds DNS Server property on a first network connection w/ IPEnabled and Default Gateway on MyServer. 
            
        .Example
            Add-DNSServer -ComputerName MyServer -DNS "3.3.3.3" -Name "Intel(R) 82578DM Gigabit Network Connection"
            Description
            -----------
            Adds DNS Server property on "Intel(R) 82578DM Gigabit Network Connection" on MyServer
            
        .OUTPUTS
            String
            
        .INPUTS
            System.String
            
        .Link
            N/A
            
        .Notes
            NAME:      Add-DNSServer
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding(SupportsShouldProcess=$true)]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME,
        
        [Parameter(Mandatory=$True)]
        [String[]]$DNSServers,
        
        [Parameter(ValueFromPipelineByPropertyName=$true)]
        [String]$Name
    )
    Begin
    {
        function ConvertFrom-SetDNSServerSearchOrderResult($Result)
        {
            Switch -exact ($Result)
            {
                0	{"Successful completion. No reboot is required."}
                1	{"Successful completion. Reboot is required."}
                64	{"Method not supported on this platform."}
                65	{"Unknown failure."}
                66	{"Invalid subnet mask."}
                67	{"An error occurred while processing an instance that is returned."}
                68	{"Invalid input parameter."}
                69	{"More than five gateways specified."}
                70	{"Invalid IP address."}
                71	{"Invalid gateway IP address."}
                72	{"An error occurred while accessing the registry for the requested information."}
                73	{"Invalid domain name."}
                74	{"Invalid host name."}
                75	{"No primary or secondary WINS server defined."}
                76	{"Invalid file."}
                77	{"Invalid system path."}
                78	{"File copy failed."}
                79	{"Invalid security parameter."}
                80	{"Unable to configure TCP/IP service."}
                81	{"Unable to configure DHCP service."}
                82	{"Unable to renew DHCP lease."}
                83	{"Unable to release DHCP lease."}
                84	{"IP not enabled on adapter."}
                85	{"IPX not enabled on adapter."}
                86	{"Frame or network number bounds error."}
                87	{"Invalid frame type."}
                88	{"Invalid network number."}
                89	{"Duplicate network number."}
                90	{"Parameter out of bounds."}
                91	{"Access denied."}
                92	{"Out of memory."}
                93	{"Already exists."}
                94	{"Path, file, or object not found."}
                95	{"Unable to notify service."}
                96	{"Unable to notify DNS service."}
                97	{"Interface not configurable."}
                98	{"Not all DHCP leases can be released or renewed."}
                100	{"DHCP not enabled on adapter."}
            }
        }
        
        Write-Verbose " [Add-DNSServer] :: Start Begin"
        Write-Verbose " [Add-DNSServer] :: DNSServers   - $DNSServers"
    }
    Process 
    {
        Write-Verbose " [Add-DNSServer] :: Start Process"
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
            
        }
        
        Write-Verbose " [Add-DNSServer] :: `$ComputerName - $ComputerName"
        Write-Verbose " [Add-DNSServer] :: Testing Connectivity"
        
        if(Test-Host $ComputerName -TCPPort 135)
        {
            Write-Verbose " [Add-DNSServer] :: Connectivity Passed"
            try
            {
                if($Name)
                {
                    $Query = "SELECT * FROM Win32_NetworkAdapterConfiguration WHERE Description='$Name'"
                    Write-Verbose " [Add-DNSServer] :: Getting NICs using - Get-WmiObject -Query $Query -ComputerName $ComputerName -ea STOP"
                    $NIC = Get-WmiObject -Query $Query -ComputerName $ComputerName -ea STOP 
                }
                else
                {
                    $Query = "SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled=TRUE"
                    Write-Verbose " [Add-DNSServer] :: Getting NICs using - Get-WmiObject -Query $Query -ComputerName $ComputerName -ea STOP"
                    $NIC = Get-WmiObject -Query $Query -ComputerName $ComputerName -ea STOP | ?{$_.DefaultIPGateway} | Select -First 1
                }
                
                Write-Verbose " [Add-DNSServer] :: Creating DNS Server list using existing and new DNS Servers"
                $NewDNSServers = $NIC.DNSServerSearchOrder 
                
                Write-Verbose " [Add-DNSServer] :: Current DNS Servers - $NewDNSServers"
                $DNSServers | %{$NewDNSServers += $_}
                $NewDNSServers = $NewDNSServers | select -Unique
                
                Write-Verbose " [Add-DNSServer] :: New DNS Servers - $NewDNSServers"
                
                if($PSCmdlet.ShouldProcess($NIC.Description,"Adding DNS Server(s) [$NewDNSServers]"))
                {
                    $Result = $NIC.SetDNSServerSearchOrder($NewDNSServers)
                    Write-Verbose " [Add-DNSServer] :: Converting Return code [$($Result.ReturnValue)] to String"
                    ConvertFrom-SetDNSServerSearchOrderResult $Result.ReturnValue
                }
 
            }
            catch
            {
                Write-Host " [Add-DNSServer] ::  Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
            }
        }
        else
        {
            Write-Host " Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
        }
        Write-Verbose " [Add-DNSServer] :: End Process"
    }
}
    
#endregion # Add-DNSServer


#region Get-LocalTime

function Get-LocalTime
{
        
    <#
        .Synopsis 
            Gets the local time for specified host.
            
        .Description
            Gets the local time for specified host.
            
        .Parameter ComputerName
            Name of the Computer to get the Computer Processor info from (Default is localhost.)
            
        .Example
            Get-LocalTime
            Description
            -----------
            Gets local time from local machine
    
        .Example
            Get-LocalTime -ComputerName MyServer
            Description
            -----------
            Gets local time on MyServer
            
        .Example
            $Servers | Get-LocalTime
            Description
            -----------
            Gets local time for each machine in the pipeline
            
        .OUTPUTS
            PSCustomObject
            
        .INPUTS
            System.String
            
        .Link
            N/A
            
        .Notes
            NAME:      Get-LocalTime
            AUTHOR:    bsonposh
            Website:   http://www.bsonposh.com
            Version:   1
            #Requires -Version 2.0
    #>
    
    [Cmdletbinding()]
    Param(
        [alias('dnsHostName')]
        [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
        [string]$ComputerName = $Env:COMPUTERNAME
    )
    
    Process 
    {
    
        if($ComputerName -match "(.*)(\$)$")
        {
            $ComputerName = $ComputerName -replace "(.*)(\$)$",'$1'
        }
        if(Test-Host -ComputerName $ComputerName -TCPPort 135)
        {
            try
            {
                $Entries = Get-WmiObject Win32_LocalTime -ComputerName $ComputerName -ea STOP
                $TimeZone = Get-WmiObject Win32_TimeZone -ComputerName $ComputerName -ea STOP
                foreach($Entry in $Entries)
                {
                    $DateString = "{0}{1:0#}{2:0#}{3:0#}{4:0#}{5:0#}" -f $Entry.Year,$Entry.Month,$Entry.Day,$Entry.hour,$Entry.Minute,$Entry.Second
                    $myobj = @{
                        ComputerName = $ComputerName
                        Date         = [System.DateTime]::ParseExact($DateString,"yyyyMMddHHmmss",$null)
                        TimeZone     = $TimeZone.Description
                        TimeZoneBias = $TimeZone.Bias
                        Day          = $Entry.Day
                        DayOfWeek    = $Entry.DayOfWeek
                        Hour         = $Entry.Hour
                        Milliseconds = $Entry.Milliseconds
                        Minute       = $Entry.Minute
                        Month        = $Entry.Month
                        Quarter      = $Entry.Quarter
                        Second       = $Entry.Second
                        WeekInMonth  = $Entry.WeekInMonth
                        Year         = $Entry.Year
                    }
                    $obj = New-Object PSObject -Property $myobj
                    $obj.PSTypeNames.Clear()
                    $obj.PSTypeNames.Add('BSonPosh.Computer.LocalTime')
                    $obj
                }
            }
            catch
            {
                Write-Host " Host [$ComputerName] Failed with Error: $($Error[0])" -ForegroundColor Red
            }
        }
        else
        {
            Write-Host " Host [$ComputerName] Failed Connectivity Test " -ForegroundColor Red
        }
    
    }
}
    
#endregion # Get-LocalTime


#region Lock-workstation

function Lock-workstation
{
	if(!(Get-Command -CommandType Function -Name LockWorkStation))
	{	
		New-PInvoke -Library User32 -Signature "void LockWorkStation()"
	}
	LockWorkStation
}

#endregion Lock-workstation